Skip to content

Commit 1472f95

Browse files
gkurtclaude
andauthored
refactor!: move ink integration to padrone/ink entry point (#15)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 96a0c35 commit 1472f95

26 files changed

Lines changed: 132 additions & 66 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'padrone': major
3+
---
4+
5+
Optional integrations are now exported from dedicated subpath entry points so bundlers that don't tree-shake re-exports keep their dependencies out of the main bundle. Update imports as follows:
6+
7+
- `padroneInk`, `isReactElement`, `InkOptions``'padrone/ink'`
8+
- `padroneMcp`, `WithMcp`, `PadroneMcpPreferences``'padrone/mcp'`
9+
- `padroneServe`, `WithServe``'padrone/serve'`
10+
- `padroneTracing`, `WithTracing`, `PadroneTracer`, `PadroneTracingConfig`, `OtelSpan`, `OtelTracer`, `OtelTracerProvider``'padrone/tracing'`
11+
- `padroneCompletion`, `WithCompletion``'padrone/completion'`
12+
- `padroneMan`, `WithMan``'padrone/man'`

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ When asked to commit with a changeset, create a concise changeset suitable for a
8383

8484
**Interceptor system**: Onion model with 7 phases: start → parse → route → validate → execute → (error) → shutdown. `collectInterceptors()` in `exec.ts` walks the parent chain (root outermost, subcommand innermost). Start/parse use root interceptors only. Route/validate/execute use the full collected chain (root + command). Error/shutdown run in two layers: command-level interceptors first (for validate/execute failures), then root-level interceptors (for all failures including parse). All interceptor phase contexts include `caller` (the invocation method: 'cli', 'eval', 'run', etc.) and `signal` (AbortSignal for cancellation). `defineInterceptor(meta, factory)` is the recommended API — the factory is called fresh per execution, enabling cross-phase state sharing via closures. Supports `.provides<T>()` and `.requires<T>()` for typed context (type-level only). Interceptors with the same `id` are deduplicated (last wins). Signal handling is implemented as a start-phase interceptor (`padroneSignalHandling`) that creates an AbortController and propagates it via `next({ signal })`. Error help display (routing/validation errors in CLI mode) is handled by the help extension's error phase, not hardcoded in exec.ts.
8585

86-
**Extension system**: Build-time composition via `.extend(extension)`. A `PadroneExtension` is a function that receives the builder and returns a modified builder, enabling reusable command/config bundles. Unlike interceptors (which hook into runtime phases), extensions operate at definition time to compose commands, arguments, and configuration. Built-in extensions are included by default via `createPadrone()`: help (-1000), version (-1000), repl (-1000), color (-1001), suggestions (-500), signal (-2000), autoOutput (-1100), stdin (-1001), interactive (-999). Numbers are interceptor `order` values (lower = outermost). User-facing builtins (help, version, repl) can be individually disabled via `{ builtins: { help: false } }`. Advanced opt-in extensions: completion, logger, timing, progress, man, mcp, serve, update-check, tracing, ink, env, config.
86+
**Extension system**: Build-time composition via `.extend(extension)`. A `PadroneExtension` is a function that receives the builder and returns a modified builder, enabling reusable command/config bundles. Unlike interceptors (which hook into runtime phases), extensions operate at definition time to compose commands, arguments, and configuration. Built-in extensions are included by default via `createPadrone()`: help (-1000), version (-1000), repl (-1000), color (-1001), suggestions (-500), signal (-2000), autoOutput (-1100), stdin (-1001), interactive (-999). Numbers are interceptor `order` values (lower = outermost). User-facing builtins (help, version, repl) can be individually disabled via `{ builtins: { help: false } }`. Advanced opt-in extensions imported from `'padrone'`: logger, timing, progress, update-check, env, config. Optional integrations with heavier transitive surfaces live in their own subpath entry points so the main bundle stays lean: `padrone/ink`, `padrone/mcp`, `padrone/serve`, `padrone/tracing`, `padrone/completion`, `padrone/man`.
8787

8888
**Flags vs aliases vs negatives**: `flags` = single-char short flags (`-v`), stackable. `alias` = multi-char alternative long names (`--dry-run`). `autoAlias` (default: true) auto-generates kebab-case aliases for camelCase option names. `negative` = custom negation keyword(s) for booleans (`negative: 'remote'` makes `--remote` set the arg to `false` and disables `--no-` prefix). Set to `''` or `[]` to only disable the prefix.
8989

docs/src/content/docs/guides/plugins.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ Additional opt-in extensions are available for advanced features:
4141
| `padroneEnv(schema)` | `'padrone'` | Parse environment variables into args |
4242
| `padroneConfig(options)` | `'padrone'` | Load args from config files |
4343
| `padroneProgress(config)` | `'padrone'` | Auto-managed progress indicators |
44-
| `padroneCompletion()` | `'padrone'` | Shell completion generation |
4544
| `padroneLogger(options)` | `'padrone'` | Structured logging with levels |
4645
| `padroneTiming()` | `'padrone'` | Execution timing |
47-
| `padroneMan()` | `'padrone'` | Man page generation |
4846
| `padroneUpdateCheck(config)` | `'padrone'` | Background version checking |
49-
| `padroneMcp()` | `'padrone'` | MCP server integration |
50-
| `padroneServe()` | `'padrone'` | REST server integration |
51-
| `padroneTracing(config)` | `'padrone'` | OpenTelemetry tracing |
52-
| `padroneInk()` | `'padrone'` | React (Ink) rendering support |
47+
| `padroneInk()` | `'padrone/ink'` | React (Ink) rendering support |
48+
| `padroneMcp()` | `'padrone/mcp'` | MCP server integration |
49+
| `padroneServe()` | `'padrone/serve'` | REST server integration |
50+
| `padroneTracing(config)` | `'padrone/tracing'` | OpenTelemetry tracing |
51+
| `padroneCompletion()` | `'padrone/completion'` | Shell completion generation |
52+
| `padroneMan()` | `'padrone/man'` | Man page generation |
5353

5454
## Extensions
5555

docs/src/content/docs/reference/api.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,15 +1187,20 @@ These extensions are available as named exports from `'padrone'`:
11871187
| `padroneEnv(schema)` | Parse environment variables into args |
11881188
| `padroneConfig(options)` | Load args from config files |
11891189
| `padroneProgress(config)` | Auto-managed progress indicators |
1190-
| `padroneCompletion()` | Shell completion generation |
11911190
| `padroneLogger(options)` | Structured logging with levels |
11921191
| `padroneTiming()` | Execution timing |
1193-
| `padroneMan()` | Man page generation |
11941192
| `padroneUpdateCheck(config)` | Background version checking |
1195-
| `padroneMcp()` | MCP server integration |
1196-
| `padroneServe()` | REST server integration |
1197-
| `padroneTracing(config)` | OpenTelemetry tracing |
1198-
| `padroneInk()` | React (Ink) rendering support |
1193+
1194+
The following extensions live in their own subpath imports to keep optional dependencies and large transitive surfaces out of the main bundle:
1195+
1196+
| Export | Import from | Purpose |
1197+
|--------|-------------|---------|
1198+
| `padroneInk()` | `'padrone/ink'` | React (Ink) rendering support |
1199+
| `padroneMcp()` | `'padrone/mcp'` | MCP server integration |
1200+
| `padroneServe()` | `'padrone/serve'` | REST server integration |
1201+
| `padroneTracing(config)` | `'padrone/tracing'` | OpenTelemetry tracing |
1202+
| `padroneCompletion()` | `'padrone/completion'` | Shell completion generation |
1203+
| `padroneMan()` | `'padrone/man'` | Man page generation |
11991204

12001205
The following extensions are applied automatically by `createPadrone()` and can be disabled via `builtins`:
12011206

examples/padrone-example/src/tasks.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { createPadrone, defineInterceptor, padroneInk, padroneLogger, padroneProgress, padroneTiming } from 'padrone';
1+
import { createPadrone, defineInterceptor, padroneLogger, padroneProgress, padroneTiming } from 'padrone';
2+
import { padroneInk } from 'padrone/ink';
23
import { zodAsyncStream } from 'padrone/zod';
34
import * as z from 'zod/v4';
45
import { addTask, getTask, getTasks, removeTask, setTaskStatus, updateTask } from './tasks-store.ts';

packages/padrone/package.json

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,16 @@
6868
"./codegen": {
6969
"padrone@dev": "./src/codegen/index.ts",
7070
"import": {
71-
"types": "./dist/codegen.d.mts",
72-
"default": "./dist/codegen.mjs"
71+
"types": "./dist/codegen/index.d.mts",
72+
"default": "./dist/codegen/index.mjs"
7373
},
7474
"source": "./src/codegen/index.ts"
7575
},
7676
"./docs": {
7777
"padrone@dev": "./src/docs/index.ts",
7878
"import": {
79-
"types": "./dist/docs.d.mts",
80-
"default": "./dist/docs.mjs"
79+
"types": "./dist/docs/index.d.mts",
80+
"default": "./dist/docs/index.mjs"
8181
},
8282
"source": "./src/docs/index.ts"
8383
},
@@ -89,10 +89,58 @@
8989
},
9090
"source": "./src/zod.ts"
9191
},
92+
"./ink": {
93+
"padrone@dev": "./src/ink.ts",
94+
"import": {
95+
"types": "./dist/ink.d.mts",
96+
"default": "./dist/ink.mjs"
97+
},
98+
"source": "./src/ink.ts"
99+
},
100+
"./mcp": {
101+
"padrone@dev": "./src/mcp.ts",
102+
"import": {
103+
"types": "./dist/mcp.d.mts",
104+
"default": "./dist/mcp.mjs"
105+
},
106+
"source": "./src/mcp.ts"
107+
},
108+
"./serve": {
109+
"padrone@dev": "./src/serve.ts",
110+
"import": {
111+
"types": "./dist/serve.d.mts",
112+
"default": "./dist/serve.mjs"
113+
},
114+
"source": "./src/serve.ts"
115+
},
116+
"./tracing": {
117+
"padrone@dev": "./src/tracing.ts",
118+
"import": {
119+
"types": "./dist/tracing.d.mts",
120+
"default": "./dist/tracing.mjs"
121+
},
122+
"source": "./src/tracing.ts"
123+
},
124+
"./completion": {
125+
"padrone@dev": "./src/completion.ts",
126+
"import": {
127+
"types": "./dist/completion.d.mts",
128+
"default": "./dist/completion.mjs"
129+
},
130+
"source": "./src/completion.ts"
131+
},
132+
"./man": {
133+
"padrone@dev": "./src/man.ts",
134+
"import": {
135+
"types": "./dist/man.d.mts",
136+
"default": "./dist/man.mjs"
137+
},
138+
"source": "./src/man.ts"
139+
},
92140
"./package.json": "./package.json"
93141
},
94142
"scripts": {
95-
"build": "tsdown src/index.ts src/test.ts src/zod.ts src/codegen/index.ts src/docs/index.ts --dts --sourcemap",
143+
"build": "tsdown src/index.ts src/test.ts src/zod.ts src/ink.ts src/mcp.ts src/serve.ts src/tracing.ts src/completion.ts src/man.ts src/codegen/index.ts src/docs/index.ts --dts --sourcemap --unbundle",
96144
"start": "bun --conditions=padrone@dev src/cli/index.ts",
97145
"dev": "bun --conditions=padrone@dev --watch src/cli/index.ts",
98146
"test": "bun test --conditions=padrone@dev",

packages/padrone/src/completion.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export type { WithCompletion } from './extension/completion.ts';
2+
export { padroneCompletion } from './extension/completion.ts';

packages/padrone/src/extension/completion.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export type WithCompletion<T> = WithCommand<T, 'completion', CompletionCommand>;
2121
*
2222
* Usage:
2323
* ```ts
24+
* import { createPadrone } from 'padrone';
25+
* import { padroneCompletion } from 'padrone/completion';
26+
*
2427
* createPadrone('my-cli').extend(padroneCompletion())
2528
* ```
2629
*/

packages/padrone/src/extension/index.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,15 @@ export type { WithAsync } from '../util/type-utils.ts';
22
export type { PadroneAutoOutputOptions } from './auto-output.ts';
33
export { padroneAutoOutput } from './auto-output.ts';
44
export { padroneColor } from './color.ts';
5-
export type { WithCompletion } from './completion.ts';
6-
export { padroneCompletion } from './completion.ts';
75
export type { PadroneConfigOptions } from './config.ts';
86
export { padroneConfig } from './config.ts';
97
export type { PadroneEnvOptions } from './env.ts';
108
export { padroneEnv } from './env.ts';
119
export type { HelpCommand, WithHelp } from './help.ts';
1210
export { padroneHelp } from './help.ts';
13-
export type { InkOptions } from './ink.ts';
14-
export { isReactElement, padroneInk } from './ink.ts';
1511
export { padroneInteractive } from './interactive.ts';
1612
export type { PadroneLogger, PadroneLoggerConfig, PadroneLogLevel, WithLogger } from './logger.ts';
1713
export { padroneLogger } from './logger.ts';
18-
export type { WithMan } from './man.ts';
19-
export { padroneMan } from './man.ts';
20-
export type { WithMcp } from './mcp.ts';
21-
export { padroneMcp } from './mcp.ts';
2214
export type {
2315
PadroneProgressConfig,
2416
PadroneProgressDefaults,
@@ -31,15 +23,11 @@ export type { PadroneProgressRenderer } from './progress-renderer.ts';
3123
export { createTerminalProgress } from './progress-renderer.ts';
3224
export type { WithRepl } from './repl.ts';
3325
export { padroneRepl } from './repl.ts';
34-
export type { WithServe } from './serve.ts';
35-
export { padroneServe } from './serve.ts';
3626
export { padroneSignalHandling } from './signal.ts';
3727
export { padroneStdin } from './stdin.ts';
3828
export { padroneSuggestions } from './suggestions.ts';
3929
export type { PadroneTimingOptions } from './timing.ts';
4030
export { padroneTiming } from './timing.ts';
41-
export type { OtelSpan, OtelTracer, OtelTracerProvider, PadroneTracer, PadroneTracingConfig, WithTracing } from './tracing.ts';
42-
export { padroneTracing } from './tracing.ts';
4331
export { padroneUpdateCheck } from './update-check.ts';
4432
export type { VersionCommand, WithVersion } from './version.ts';
4533
export { padroneVersion } from './version.ts';

packages/padrone/src/extension/ink.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ function createInkInterceptor(rawOptions?: InkOptions) {
7878
* Requires `ink` and `react` as peer dependencies.
7979
*
8080
* ```ts
81-
* import { createPadrone, padroneInk } from 'padrone';
81+
* import { createPadrone } from 'padrone';
82+
* import { padroneInk } from 'padrone/ink';
8283
*
8384
* const program = createPadrone('my-tui')
8485
* .extend(padroneInk())

0 commit comments

Comments
 (0)