effect 4.0.0-beta.25 → 4.0.0-beta.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/Config.js +4 -4
  2. package/dist/Config.js.map +1 -1
  3. package/dist/Effect.d.ts +20 -13
  4. package/dist/Effect.d.ts.map +1 -1
  5. package/dist/Effect.js +2 -1
  6. package/dist/Effect.js.map +1 -1
  7. package/dist/Runtime.d.ts +66 -0
  8. package/dist/Runtime.d.ts.map +1 -1
  9. package/dist/Runtime.js +72 -5
  10. package/dist/Runtime.js.map +1 -1
  11. package/dist/Schema.d.ts +15 -32
  12. package/dist/Schema.d.ts.map +1 -1
  13. package/dist/Schema.js +9 -17
  14. package/dist/Schema.js.map +1 -1
  15. package/dist/SchemaAST.js +91 -2
  16. package/dist/SchemaAST.js.map +1 -1
  17. package/dist/SchemaGetter.d.ts +3 -3
  18. package/dist/SchemaRepresentation.d.ts.map +1 -1
  19. package/dist/SchemaRepresentation.js +12 -8
  20. package/dist/SchemaRepresentation.js.map +1 -1
  21. package/dist/Stdio.d.ts +10 -2
  22. package/dist/Stdio.d.ts.map +1 -1
  23. package/dist/Stdio.js +18 -0
  24. package/dist/Stdio.js.map +1 -1
  25. package/dist/internal/schema/representation.js +7 -3
  26. package/dist/internal/schema/representation.js.map +1 -1
  27. package/dist/internal/schema/to-codec.js +7 -10
  28. package/dist/internal/schema/to-codec.js.map +1 -1
  29. package/dist/unstable/ai/AiError.d.ts +6 -3
  30. package/dist/unstable/ai/AiError.d.ts.map +1 -1
  31. package/dist/unstable/ai/AiError.js +8 -4
  32. package/dist/unstable/ai/AiError.js.map +1 -1
  33. package/dist/unstable/ai/LanguageModel.js +7 -5
  34. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  35. package/dist/unstable/cli/CliError.d.ts +19 -52
  36. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  37. package/dist/unstable/cli/CliError.js +21 -53
  38. package/dist/unstable/cli/CliError.js.map +1 -1
  39. package/dist/unstable/cli/Command.d.ts +117 -62
  40. package/dist/unstable/cli/Command.d.ts.map +1 -1
  41. package/dist/unstable/cli/Command.js +95 -32
  42. package/dist/unstable/cli/Command.js.map +1 -1
  43. package/dist/unstable/cli/GlobalFlag.d.ts +1 -1
  44. package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
  45. package/dist/unstable/cli/internal/command.d.ts +27 -10
  46. package/dist/unstable/cli/internal/command.d.ts.map +1 -1
  47. package/dist/unstable/cli/internal/command.js +40 -23
  48. package/dist/unstable/cli/internal/command.js.map +1 -1
  49. package/dist/unstable/cli/internal/config.js +42 -0
  50. package/dist/unstable/cli/internal/config.js.map +1 -1
  51. package/dist/unstable/cli/internal/help.d.ts +4 -4
  52. package/dist/unstable/cli/internal/help.d.ts.map +1 -1
  53. package/dist/unstable/cli/internal/help.js +25 -7
  54. package/dist/unstable/cli/internal/help.js.map +1 -1
  55. package/dist/unstable/cli/internal/parser.js +26 -6
  56. package/dist/unstable/cli/internal/parser.js.map +1 -1
  57. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  58. package/dist/unstable/httpapi/HttpApiBuilder.js +1 -7
  59. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  60. package/dist/unstable/httpapi/HttpApiClient.d.ts +6 -6
  61. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  62. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  63. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +10 -10
  64. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  65. package/dist/unstable/httpapi/HttpApiEndpoint.js +2 -2
  66. package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
  67. package/dist/unstable/httpapi/HttpApiError.d.ts +6 -15
  68. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  69. package/dist/unstable/httpapi/HttpApiError.js +16 -21
  70. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  71. package/dist/unstable/reactivity/Atom.d.ts +56 -0
  72. package/dist/unstable/reactivity/Atom.d.ts.map +1 -1
  73. package/dist/unstable/reactivity/Atom.js +66 -0
  74. package/dist/unstable/reactivity/Atom.js.map +1 -1
  75. package/dist/unstable/reactivity/AtomHttpApi.d.ts +2 -2
  76. package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
  77. package/dist/unstable/rpc/RpcServer.d.ts +3 -0
  78. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  79. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  80. package/dist/unstable/sql/SqlSchema.d.ts +2 -2
  81. package/dist/unstable/sql/SqlSchema.d.ts.map +1 -1
  82. package/dist/unstable/sql/SqlSchema.js.map +1 -1
  83. package/package.json +1 -1
  84. package/src/Config.ts +4 -4
  85. package/src/Effect.ts +29 -9
  86. package/src/Runtime.ts +95 -5
  87. package/src/Schema.ts +20 -52
  88. package/src/SchemaAST.ts +127 -2
  89. package/src/SchemaGetter.ts +3 -3
  90. package/src/SchemaRepresentation.ts +12 -8
  91. package/src/Stdio.ts +21 -2
  92. package/src/internal/schema/representation.ts +8 -4
  93. package/src/internal/schema/to-codec.ts +7 -17
  94. package/src/unstable/ai/AiError.ts +8 -4
  95. package/src/unstable/ai/LanguageModel.ts +8 -5
  96. package/src/unstable/cli/CliError.ts +43 -55
  97. package/src/unstable/cli/Command.ts +348 -180
  98. package/src/unstable/cli/GlobalFlag.ts +1 -1
  99. package/src/unstable/cli/internal/command.ts +62 -32
  100. package/src/unstable/cli/internal/config.ts +49 -0
  101. package/src/unstable/cli/internal/help.ts +41 -16
  102. package/src/unstable/cli/internal/parser.ts +36 -10
  103. package/src/unstable/httpapi/HttpApiBuilder.ts +1 -7
  104. package/src/unstable/httpapi/HttpApiClient.ts +6 -6
  105. package/src/unstable/httpapi/HttpApiEndpoint.ts +4 -4
  106. package/src/unstable/httpapi/HttpApiError.ts +23 -21
  107. package/src/unstable/reactivity/Atom.ts +132 -0
  108. package/src/unstable/reactivity/AtomHttpApi.ts +2 -2
  109. package/src/unstable/rpc/RpcServer.ts +5 -0
  110. package/src/unstable/sql/SqlSchema.ts +2 -2
@@ -14,14 +14,15 @@ import * as Predicate from "../../Predicate.ts"
14
14
  import * as References from "../../References.ts"
15
15
  import * as Result from "../../Result.ts"
16
16
  import * as ServiceMap from "../../ServiceMap.ts"
17
+ import * as Stdio from "../../Stdio.ts"
17
18
  import * as Terminal from "../../Terminal.ts"
18
19
  import type { NoInfer, Simplify } from "../../Types.ts"
19
20
  import type { ChildProcessSpawner } from "../process/ChildProcessSpawner.ts"
20
21
  import * as CliError from "./CliError.ts"
21
22
  import * as CliOutput from "./CliOutput.ts"
22
23
  import * as GlobalFlag from "./GlobalFlag.ts"
23
- import { checkForDuplicateFlags, makeCommand, toImpl, TypeId } from "./internal/command.ts"
24
- import { parseConfig } from "./internal/config.ts"
24
+ import { checkForDuplicateFlags, makeCommand, makeParser, toImpl, TypeId } from "./internal/command.ts"
25
+ import { mergeConfig, parseConfig } from "./internal/config.ts"
25
26
  import { getGlobalFlagsForCommandPath, getGlobalFlagsForCommandTree, getHelpForCommandPath } from "./internal/help.ts"
26
27
  import * as Lexer from "./internal/lexer.ts"
27
28
  import * as Parser from "./internal/parser.ts"
@@ -46,7 +47,7 @@ import * as Param from "./Param.ts"
46
47
  * import { Argument, Command, Flag } from "effect/unstable/cli"
47
48
  *
48
49
  * // Simple command with no configuration
49
- * const version: Command.Command<"version", {}, never, never> = Command.make(
50
+ * const version: Command.Command<"version", {}, {}, never, never> = Command.make(
50
51
  * "version"
51
52
  * )
52
53
  *
@@ -58,6 +59,7 @@ import * as Param from "./Param.ts"
58
59
  * readonly force: boolean
59
60
  * readonly files: ReadonlyArray<string>
60
61
  * },
62
+ * {},
61
63
  * never,
62
64
  * never
63
65
  * > = Command.make("deploy", {
@@ -75,14 +77,15 @@ import * as Param from "./Param.ts"
75
77
  * @since 4.0.0
76
78
  * @category models
77
79
  */
78
- export interface Command<Name extends string, Input, E = never, R = never> extends
79
- Pipeable,
80
- Effect.Yieldable<
81
- Command<Name, Input, E, R>,
82
- Input,
83
- never,
84
- CommandContext<Name>
85
- >
80
+ export interface Command<Name extends string, Input, ContextInput = {}, E = never, R = never>
81
+ extends
82
+ Pipeable,
83
+ Effect.Yieldable<
84
+ Command<Name, Input, ContextInput, E, R>,
85
+ ContextInput,
86
+ never,
87
+ CommandContext<Name>
88
+ >
86
89
  {
87
90
  readonly [TypeId]: typeof TypeId
88
91
 
@@ -183,6 +186,21 @@ export declare namespace Command {
183
186
  | Config
184
187
  }
185
188
 
189
+ /**
190
+ * Configuration shape accepted by `Command.withSharedFlags`.
191
+ *
192
+ * Only flags are allowed here; arguments are intentionally excluded.
193
+ *
194
+ * @since 4.0.0
195
+ * @category models
196
+ */
197
+ export interface FlagConfig {
198
+ readonly [key: string]:
199
+ | Param.Param<typeof Param.flagKind, any>
200
+ | ReadonlyArray<Param.Param<typeof Param.flagKind, any> | FlagConfig>
201
+ | FlagConfig
202
+ }
203
+
186
204
  /**
187
205
  * Utilities for working with command configurations.
188
206
  *
@@ -244,7 +262,7 @@ export declare namespace Command {
244
262
  * @since 4.0.0
245
263
  * @category models
246
264
  */
247
- export type Any = Command<string, unknown, unknown, unknown>
265
+ export type Any = Command<string, unknown, unknown, unknown, unknown>
248
266
 
249
267
  /**
250
268
  * A grouped set of subcommands used by `Command.withSubcommands`.
@@ -272,7 +290,7 @@ export declare namespace Command {
272
290
  * @since 4.0.0
273
291
  * @category utility types
274
292
  */
275
- export type Environment = FileSystem.FileSystem | Path.Path | Terminal.Terminal | ChildProcessSpawner
293
+ export type Environment = FileSystem.FileSystem | Path.Path | Terminal.Terminal | ChildProcessSpawner | Stdio.Stdio
276
294
 
277
295
  /**
278
296
  * A utility type to extract the error type from a `Command`.
@@ -283,6 +301,7 @@ export type Environment = FileSystem.FileSystem | Path.Path | Terminal.Terminal
283
301
  export type Error<C> = C extends Command<
284
302
  infer _Name,
285
303
  infer _Input,
304
+ infer _ContextInput,
286
305
  infer _Error,
287
306
  infer _Requirements
288
307
  > ? _Error :
@@ -301,10 +320,12 @@ export type Error<C> = C extends Command<
301
320
  * import { Console, Effect } from "effect"
302
321
  * import { Command, Flag } from "effect/unstable/cli"
303
322
  *
304
- * const parent = Command.make("app", {
305
- * verbose: Flag.boolean("verbose"),
306
- * config: Flag.string("config")
307
- * })
323
+ * const parent = Command.make("app").pipe(
324
+ * Command.withSharedFlags({
325
+ * verbose: Flag.boolean("verbose"),
326
+ * config: Flag.string("config")
327
+ * })
328
+ * )
308
329
  *
309
330
  * const child = Command.make("deploy", {
310
331
  * target: Flag.string("target")
@@ -466,7 +487,7 @@ export const make: {
466
487
  * @since 4.0.0
467
488
  * @category constructors
468
489
  */
469
- <Name extends string>(name: Name): Command<Name, {}, never, never>
490
+ <Name extends string>(name: Name): Command<Name, {}, {}, never, never>
470
491
 
471
492
  /* ========================================================================== */
472
493
  /* Constructors */
@@ -525,7 +546,7 @@ export const make: {
525
546
  * @since 4.0.0
526
547
  * @category constructors
527
548
  */
528
- <Name extends string, const Config extends Command.Config>(name: Name, config: Config): Command<Name, Command.Config.Infer<Config>, never, never>
549
+ <Name extends string, const Config extends Command.Config>(name: Name, config: Config): Command<Name, Command.Config.Infer<Config>, {}, never, never>
529
550
 
530
551
  /* ========================================================================== */
531
552
  /* Constructors */
@@ -588,7 +609,7 @@ export const make: {
588
609
  name: Name,
589
610
  config: Config,
590
611
  handler: (config: Command.Config.Infer<Config>) => Effect.Effect<void, E, R>
591
- ): Command<Name, Command.Config.Infer<Config>, E, Exclude<R, GlobalFlag.BuiltInSettingContext>>
612
+ ): Command<Name, Command.Config.Infer<Config>, {}, E, Exclude<R, GlobalFlag.BuiltInSettingContext>>
592
613
  } = ((
593
614
  name: string,
594
615
  config?: Command.Config,
@@ -659,9 +680,9 @@ export const withHandler: {
659
680
  * @since 4.0.0
660
681
  * @category combinators
661
682
  */
662
- <A, R, E>(handler: (value: A) => Effect.Effect<void, E, R>): <Name extends string, XR, XE>(
663
- self: Command<Name, A, XE, XR>
664
- ) => Command<Name, A, E, Exclude<R, GlobalFlag.BuiltInSettingContext>>
683
+ <A, R, E>(handler: (value: A) => Effect.Effect<void, E, R>): <Name extends string, XR, XE, ContextInput>(
684
+ self: Command<Name, A, ContextInput, XE, XR>
685
+ ) => Command<Name, A, ContextInput, E, Exclude<R, GlobalFlag.BuiltInSettingContext>>
665
686
  /* ========================================================================== */
666
687
  /* Combinators */
667
688
  /* ========================================================================== */
@@ -690,14 +711,14 @@ export const withHandler: {
690
711
  * @since 4.0.0
691
712
  * @category combinators
692
713
  */
693
- <Name extends string, A, XR, XE, R, E>(
694
- self: Command<Name, A, XE, XR>,
714
+ <Name extends string, A, XR, XE, R, E, ContextInput>(
715
+ self: Command<Name, A, ContextInput, XE, XR>,
695
716
  handler: (value: A) => Effect.Effect<void, E, R>
696
- ): Command<Name, A, E, Exclude<R, GlobalFlag.BuiltInSettingContext>>
697
- } = dual(2, <Name extends string, A, XR, XE, R, E>(
698
- self: Command<Name, A, XE, XR>,
717
+ ): Command<Name, A, ContextInput, E, Exclude<R, GlobalFlag.BuiltInSettingContext>>
718
+ } = dual(2, <Name extends string, A, XR, XE, R, E, ContextInput>(
719
+ self: Command<Name, A, ContextInput, XE, XR>,
699
720
  handler: (value: A) => Effect.Effect<void, E, R>
700
- ): Command<Name, A, E, Exclude<R, GlobalFlag.BuiltInSettingContext>> =>
721
+ ): Command<Name, A, ContextInput, E, Exclude<R, GlobalFlag.BuiltInSettingContext>> =>
701
722
  makeCommand({ ...toImpl(self), handle: handler }))
702
723
 
703
724
  interface SubcommandGroupInternal {
@@ -755,7 +776,7 @@ const normalizeSubcommandEntries = (
755
776
  * Adds subcommands to a command, creating a hierarchical command structure.
756
777
  *
757
778
  * Subcommands can access their parent's parsed configuration by yielding the parent
758
- * command within their handler. This enables patterns like global flags that affect
779
+ * command within their handler. This enables shared parent flags that affect
759
780
  * all subcommands.
760
781
  *
761
782
  * @example
@@ -763,10 +784,12 @@ const normalizeSubcommandEntries = (
763
784
  * import { Console, Effect } from "effect"
764
785
  * import { Command, Flag } from "effect/unstable/cli"
765
786
  *
766
- * // Parent command with global flags
767
- * const git = Command.make("git", {
768
- * verbose: Flag.boolean("verbose")
769
- * })
787
+ * // Parent command with shared flags
788
+ * const git = Command.make("git").pipe(
789
+ * Command.withSharedFlags({
790
+ * verbose: Flag.boolean("verbose")
791
+ * })
792
+ * )
770
793
  *
771
794
  * // Subcommand that accesses parent config
772
795
  * const clone = Command.make("clone", {
@@ -792,7 +815,7 @@ export const withSubcommands: {
792
815
  * Adds subcommands to a command, creating a hierarchical command structure.
793
816
  *
794
817
  * Subcommands can access their parent's parsed configuration by yielding the parent
795
- * command within their handler. This enables patterns like global flags that affect
818
+ * command within their handler. This enables shared parent flags that affect
796
819
  * all subcommands.
797
820
  *
798
821
  * @example
@@ -800,10 +823,12 @@ export const withSubcommands: {
800
823
  * import { Console, Effect } from "effect"
801
824
  * import { Command, Flag } from "effect/unstable/cli"
802
825
  *
803
- * // Parent command with global flags
804
- * const git = Command.make("git", {
805
- * verbose: Flag.boolean("verbose")
806
- * })
826
+ * // Parent command with shared flags
827
+ * const git = Command.make("git").pipe(
828
+ * Command.withSharedFlags({
829
+ * verbose: Flag.boolean("verbose")
830
+ * })
831
+ * )
807
832
  *
808
833
  * // Subcommand that accesses parent config
809
834
  * const clone = Command.make("clone", {
@@ -824,11 +849,12 @@ export const withSubcommands: {
824
849
  * @since 4.0.0
825
850
  * @category combinators
826
851
  */
827
- <const Subcommands extends ReadonlyArray<Command.SubcommandEntry>>(subcommands: Subcommands): <Name extends string, Input, E, R>(
828
- self: Command<Name, Input, E, R>
852
+ <const Subcommands extends ReadonlyArray<Command.SubcommandEntry>>(subcommands: Subcommands): <Name extends string, Input, E, R, ContextInput>(
853
+ self: Command<Name, Input, ContextInput, E, R>
829
854
  ) => Command<
830
855
  Name,
831
- Input,
856
+ Simplify<Input | ContextInput>,
857
+ ContextInput,
832
858
  E | ExtractSubcommandErrors<Subcommands>,
833
859
  R | Exclude<ExtractSubcommandContext<Subcommands>, CommandContext<Name>>
834
860
  >
@@ -836,7 +862,7 @@ export const withSubcommands: {
836
862
  * Adds subcommands to a command, creating a hierarchical command structure.
837
863
  *
838
864
  * Subcommands can access their parent's parsed configuration by yielding the parent
839
- * command within their handler. This enables patterns like global flags that affect
865
+ * command within their handler. This enables shared parent flags that affect
840
866
  * all subcommands.
841
867
  *
842
868
  * @example
@@ -844,10 +870,12 @@ export const withSubcommands: {
844
870
  * import { Console, Effect } from "effect"
845
871
  * import { Command, Flag } from "effect/unstable/cli"
846
872
  *
847
- * // Parent command with global flags
848
- * const git = Command.make("git", {
849
- * verbose: Flag.boolean("verbose")
850
- * })
873
+ * // Parent command with shared flags
874
+ * const git = Command.make("git").pipe(
875
+ * Command.withSharedFlags({
876
+ * verbose: Flag.boolean("verbose")
877
+ * })
878
+ * )
851
879
  *
852
880
  * // Subcommand that accesses parent config
853
881
  * const clone = Command.make("clone", {
@@ -873,10 +901,12 @@ export const withSubcommands: {
873
901
  Input,
874
902
  E,
875
903
  R,
904
+ ContextInput,
876
905
  const Subcommands extends ReadonlyArray<Command.SubcommandEntry>
877
- >(self: Command<Name, Input, E, R>, subcommands: Subcommands): Command<
906
+ >(self: Command<Name, Input, ContextInput, E, R>, subcommands: Subcommands): Command<
878
907
  Name,
879
- Input,
908
+ Simplify<Input | ContextInput>,
909
+ ContextInput,
880
910
  E | ExtractSubcommandErrors<Subcommands>,
881
911
  R | Exclude<ExtractSubcommandContext<Subcommands>, CommandContext<Name>>
882
912
  >
@@ -885,13 +915,15 @@ export const withSubcommands: {
885
915
  Input,
886
916
  E,
887
917
  R,
918
+ ContextInput,
888
919
  const Subcommands extends ReadonlyArray<Command.SubcommandEntry>
889
920
  >(
890
- self: Command<Name, Input, E, R>,
921
+ self: Command<Name, Input, ContextInput, E, R>,
891
922
  subcommands: Subcommands
892
923
  ): Command<
893
924
  Name,
894
- Input,
925
+ Simplify<Input | ContextInput>,
926
+ ContextInput,
895
927
  E | ExtractSubcommandErrors<Subcommands>,
896
928
  R | Exclude<ExtractSubcommandContext<Subcommands>, CommandContext<Name>>
897
929
  > => {
@@ -901,44 +933,46 @@ export const withSubcommands: {
901
933
  const impl = toImpl(self)
902
934
  const byName = new Map(normalized.flat.map((s) => [s.name, toImpl(s)] as const))
903
935
 
904
- // Internal type for routing - not exposed in public type
905
- type SubcommandInfo = { readonly name: string; readonly result: unknown }
906
- type InternalInput = Input & { readonly _subcommand?: SubcommandInfo }
936
+ type NextInput = Simplify<Input | ContextInput>
937
+ const SubcommandStateSymbol = Symbol("effect/cli/SubcommandState")
938
+ type SubcommandState = { readonly name: string; readonly result: unknown }
939
+ type InternalInput = NextInput & { readonly [SubcommandStateSymbol]?: SubcommandState }
907
940
 
908
941
  const parse = Effect.fnUntraced(function*(raw: ParsedTokens) {
909
- const parent = yield* impl.parse(raw)
910
-
911
942
  if (!raw.subcommand) {
912
- return parent
943
+ return (yield* impl.parse(raw)) as NextInput
913
944
  }
914
945
 
915
946
  const sub = byName.get(raw.subcommand.name)
916
947
  if (!sub) {
917
- return parent
948
+ return (yield* impl.parse(raw)) as NextInput
918
949
  }
919
950
 
951
+ const context = yield* impl.parseContext(raw)
920
952
  const result = yield* sub.parse(raw.subcommand.parsedInput)
921
- // Attach subcommand info internally for routing
922
- return Object.assign({}, parent, { _subcommand: { name: sub.name, result } }) as InternalInput
953
+ return Object.assign({}, context, { [SubcommandStateSymbol]: { name: sub.name, result } }) as NextInput
923
954
  })
924
955
 
925
- const handle = Effect.fnUntraced(function*(input: Input, path: ReadonlyArray<string>) {
956
+ const handle = Effect.fnUntraced(function*(input: NextInput, path: ReadonlyArray<string>) {
926
957
  const internal = input as InternalInput
927
- if (internal._subcommand) {
928
- const child = byName.get(internal._subcommand.name)
958
+ const selectedSubcommand = internal[SubcommandStateSymbol]
959
+
960
+ if (selectedSubcommand) {
961
+ const child = byName.get(selectedSubcommand.name)
929
962
  if (!child) {
930
- return yield* new CliError.ShowHelp({ commandPath: path })
963
+ return yield* new CliError.ShowHelp({ commandPath: path, errors: [] })
931
964
  }
932
965
  return yield* child
933
- .handle(internal._subcommand.result, [...path, child.name])
934
- .pipe(Effect.provideService(impl.service, input))
966
+ .handle(selectedSubcommand.result, [...path, child.name])
967
+ .pipe(Effect.provideService(impl.service, input as unknown as ContextInput))
935
968
  }
936
- return yield* impl.handle(input, path)
969
+ return yield* impl.handle(input as Input, path)
937
970
  })
938
971
 
939
972
  return makeCommand({
940
973
  name: impl.name,
941
974
  config: impl.config,
975
+ contextConfig: impl.contextConfig,
942
976
  description: impl.description,
943
977
  shortDescription: impl.shortDescription,
944
978
  alias: impl.alias,
@@ -948,10 +982,124 @@ export const withSubcommands: {
948
982
  service: impl.service,
949
983
  subcommands: normalized.groups,
950
984
  parse,
985
+ parseContext: impl.parseContext,
951
986
  handle
952
987
  })
953
988
  })
954
989
 
990
+ /**
991
+ * Adds flags that are inherited by subcommands.
992
+ *
993
+ * Shared flags are available to this command's handler and to descendant
994
+ * handlers via `yield* parentCommand`. Shared flags are accepted both before
995
+ * and after a selected subcommand name (npm-style).
996
+ *
997
+ * @since 4.0.0
998
+ * @category combinators
999
+ */
1000
+ export const withSharedFlags: {
1001
+ /**
1002
+ * Adds flags that are inherited by subcommands.
1003
+ *
1004
+ * Shared flags are available to this command's handler and to descendant
1005
+ * handlers via `yield* parentCommand`. Shared flags are accepted both before
1006
+ * and after a selected subcommand name (npm-style).
1007
+ *
1008
+ * @since 4.0.0
1009
+ * @category combinators
1010
+ */
1011
+ <const SharedFlags extends Command.FlagConfig>(sharedFlags: SharedFlags): <Name extends string, Input, E, R, ContextInput>(
1012
+ self: Command<Name, Input, ContextInput, E, R>
1013
+ ) => Command<
1014
+ Name,
1015
+ Simplify<Input & Command.Config.Infer<SharedFlags>>,
1016
+ Simplify<ContextInput & Command.Config.Infer<SharedFlags>>,
1017
+ E,
1018
+ R
1019
+ >
1020
+ /**
1021
+ * Adds flags that are inherited by subcommands.
1022
+ *
1023
+ * Shared flags are available to this command's handler and to descendant
1024
+ * handlers via `yield* parentCommand`. Shared flags are accepted both before
1025
+ * and after a selected subcommand name (npm-style).
1026
+ *
1027
+ * @since 4.0.0
1028
+ * @category combinators
1029
+ */
1030
+ <Name extends string, Input, E, R, ContextInput, const SharedFlags extends Command.FlagConfig>(self: Command<Name, Input, ContextInput, E, R>, sharedFlags: SharedFlags): Command<
1031
+ Name,
1032
+ Simplify<Input & Command.Config.Infer<SharedFlags>>,
1033
+ Simplify<ContextInput & Command.Config.Infer<SharedFlags>>,
1034
+ E,
1035
+ R
1036
+ >
1037
+ } = dual(
1038
+ 2,
1039
+ <Name extends string, Input, E, R, ContextInput, const SharedFlags extends Command.FlagConfig>(
1040
+ self: Command<Name, Input, ContextInput, E, R>,
1041
+ sharedFlags: SharedFlags
1042
+ ): Command<
1043
+ Name,
1044
+ Simplify<Input & Command.Config.Infer<SharedFlags>>,
1045
+ Simplify<ContextInput & Command.Config.Infer<SharedFlags>>,
1046
+ E,
1047
+ R
1048
+ > => {
1049
+ const impl = toImpl(self)
1050
+ const sharedConfig = parseConfig(sharedFlags)
1051
+ const mergedConfig = mergeConfig(impl.config, sharedConfig)
1052
+ const mergedContextConfig = mergeConfig(impl.contextConfig, sharedConfig)
1053
+
1054
+ if (impl.subcommands.length > 0) {
1055
+ const flatSubcommands = impl.subcommands.flatMap((group) => group.commands)
1056
+ checkForDuplicateFlags(self, flatSubcommands, { contextConfig: mergedContextConfig })
1057
+ }
1058
+
1059
+ type SharedInput = Command.Config.Infer<SharedFlags>
1060
+ type NextInput = Simplify<Input & SharedInput>
1061
+ type NextContextInput = Simplify<ContextInput & SharedInput>
1062
+
1063
+ const parseShared = makeParser(sharedConfig) as (
1064
+ input: ParsedTokens
1065
+ ) => Effect.Effect<SharedInput, CliError.CliError, Environment>
1066
+
1067
+ const parse = Effect.fnUntraced(function*(raw: ParsedTokens) {
1068
+ const base = yield* impl.parse(raw)
1069
+ const shared = yield* parseShared(raw)
1070
+ return Object.assign({}, base, shared) as NextInput
1071
+ })
1072
+
1073
+ const parseContext = Effect.fnUntraced(function*(raw: ParsedTokens) {
1074
+ const base = yield* impl.parseContext(raw)
1075
+ const shared = yield* parseShared(raw)
1076
+ return Object.assign({}, base, shared) as NextContextInput
1077
+ })
1078
+
1079
+ const handle = (
1080
+ input: NextInput,
1081
+ commandPath: ReadonlyArray<string>
1082
+ ) => impl.handle(input as Input, commandPath)
1083
+
1084
+ return makeCommand({
1085
+ name: impl.name,
1086
+ config: mergedConfig,
1087
+ contextConfig: mergedContextConfig,
1088
+ description: impl.description,
1089
+ shortDescription: impl.shortDescription,
1090
+ alias: impl.alias,
1091
+ annotations: impl.annotations,
1092
+ globalFlags: impl.globalFlags,
1093
+ examples: impl.examples,
1094
+ service: impl.service as ServiceMap.Key<CommandContext<Name>, NextContextInput>,
1095
+ subcommands: impl.subcommands,
1096
+ parse,
1097
+ parseContext,
1098
+ handle
1099
+ })
1100
+ }
1101
+ )
1102
+
955
1103
  /**
956
1104
  * Declares global flags for a command scope.
957
1105
  *
@@ -969,9 +1117,9 @@ export const withGlobalFlags: {
969
1117
  * @since 4.0.0
970
1118
  * @category combinators
971
1119
  */
972
- <const GlobalFlags extends ReadonlyArray<GlobalFlag.GlobalFlag<any>>>(globalFlags: GlobalFlags): <Name extends string, Input, E, R>(
973
- self: Command<Name, Input, E, R>
974
- ) => Command<Name, Input, E, Exclude<R, ExtractGlobalFlagContext<GlobalFlags>>>
1120
+ <const GlobalFlags extends ReadonlyArray<GlobalFlag.GlobalFlag<any>>>(globalFlags: GlobalFlags): <Name extends string, Input, E, R, ContextInput>(
1121
+ self: Command<Name, Input, ContextInput, E, R>
1122
+ ) => Command<Name, Input, ContextInput, E, Exclude<R, ExtractGlobalFlagContext<GlobalFlags>>>
975
1123
  /**
976
1124
  * Declares global flags for a command scope.
977
1125
  *
@@ -980,13 +1128,27 @@ export const withGlobalFlags: {
980
1128
  * @since 4.0.0
981
1129
  * @category combinators
982
1130
  */
983
- <Name extends string, Input, E, R, const GlobalFlags extends ReadonlyArray<GlobalFlag.GlobalFlag<any>>>(self: Command<Name, Input, E, R>, globalFlags: GlobalFlags): Command<Name, Input, E, Exclude<R, ExtractGlobalFlagContext<GlobalFlags>>>
1131
+ <
1132
+ Name extends string,
1133
+ Input,
1134
+ E,
1135
+ R,
1136
+ ContextInput,
1137
+ const GlobalFlags extends ReadonlyArray<GlobalFlag.GlobalFlag<any>>
1138
+ >(self: Command<Name, Input, ContextInput, E, R>, globalFlags: GlobalFlags): Command<Name, Input, ContextInput, E, Exclude<R, ExtractGlobalFlagContext<GlobalFlags>>>
984
1139
  } = dual(
985
1140
  2,
986
- <Name extends string, Input, E, R, const GlobalFlags extends ReadonlyArray<GlobalFlag.GlobalFlag<any>>>(
987
- self: Command<Name, Input, E, R>,
1141
+ <
1142
+ Name extends string,
1143
+ Input,
1144
+ E,
1145
+ R,
1146
+ ContextInput,
1147
+ const GlobalFlags extends ReadonlyArray<GlobalFlag.GlobalFlag<any>>
1148
+ >(
1149
+ self: Command<Name, Input, ContextInput, E, R>,
988
1150
  globalFlags: GlobalFlags
989
- ): Command<Name, Input, E, Exclude<R, ExtractGlobalFlagContext<GlobalFlags>>> => {
1151
+ ): Command<Name, Input, ContextInput, E, Exclude<R, ExtractGlobalFlagContext<GlobalFlags>>> => {
990
1152
  const impl = toImpl(self)
991
1153
  const next = Array.from(new Set([...impl.globalFlags, ...globalFlags]))
992
1154
  return makeCommand({ ...impl, globalFlags: next })
@@ -998,12 +1160,12 @@ type ExtractGlobalFlagContext<T extends ReadonlyArray<GlobalFlag.GlobalFlag<any>
998
1160
  ? F extends GlobalFlag.Setting<infer Id, any> ? GlobalFlag.Setting.Identifier<Id>
999
1161
  : never
1000
1162
  : never
1001
- type ExtractSubcommand<T> = T extends Command<any, any, any, any> ? T
1163
+ type ExtractSubcommand<T> = T extends Command<any, any, any, any, any> ? T
1002
1164
  : T extends Command.SubcommandGroup<infer Commands> ? Commands[number]
1003
1165
  : never
1004
1166
  type ExtractSubcommandErrors<T extends ReadonlyArray<Command.SubcommandEntry>> = Error<ExtractSubcommand<T[number]>>
1005
1167
  type ExtractSubcommandContext<T extends ReadonlyArray<Command.SubcommandEntry>> = ExtractSubcommand<T[number]> extends
1006
- Command<any, any, any, infer R> ? R : never
1168
+ Command<any, any, any, any, infer R> ? R : never
1007
1169
 
1008
1170
  /**
1009
1171
  * Sets the description for a command.
@@ -1054,9 +1216,9 @@ export const withDescription: {
1054
1216
  * @since 4.0.0
1055
1217
  * @category combinators
1056
1218
  */
1057
- (description: string): <const Name extends string, Input, E, R>(
1058
- self: Command<Name, Input, E, R>
1059
- ) => Command<Name, Input, E, R>
1219
+ (description: string): <const Name extends string, Input, E, R, ContextInput>(
1220
+ self: Command<Name, Input, ContextInput, E, R>
1221
+ ) => Command<Name, Input, ContextInput, E, R>
1060
1222
  /**
1061
1223
  * Sets the description for a command.
1062
1224
  *
@@ -1081,9 +1243,9 @@ export const withDescription: {
1081
1243
  * @since 4.0.0
1082
1244
  * @category combinators
1083
1245
  */
1084
- <const Name extends string, Input, E, R>(self: Command<Name, Input, E, R>, description: string): Command<Name, Input, E, R>
1085
- } = dual(2, <const Name extends string, Input, E, R>(
1086
- self: Command<Name, Input, E, R>,
1246
+ <const Name extends string, Input, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>, description: string): Command<Name, Input, ContextInput, E, R>
1247
+ } = dual(2, <const Name extends string, Input, E, R, ContextInput>(
1248
+ self: Command<Name, Input, ContextInput, E, R>,
1087
1249
  description: string
1088
1250
  ) => makeCommand({ ...toImpl(self), description }))
1089
1251
 
@@ -1108,9 +1270,9 @@ export const withShortDescription: {
1108
1270
  * @since 4.0.0
1109
1271
  * @category combinators
1110
1272
  */
1111
- (shortDescription: string): <const Name extends string, Input, E, R>(
1112
- self: Command<Name, Input, E, R>
1113
- ) => Command<Name, Input, E, R>
1273
+ (shortDescription: string): <const Name extends string, Input, E, R, ContextInput>(
1274
+ self: Command<Name, Input, ContextInput, E, R>
1275
+ ) => Command<Name, Input, ContextInput, E, R>
1114
1276
  /**
1115
1277
  * Sets a short description for a command.
1116
1278
  *
@@ -1121,9 +1283,9 @@ export const withShortDescription: {
1121
1283
  * @since 4.0.0
1122
1284
  * @category combinators
1123
1285
  */
1124
- <const Name extends string, Input, E, R>(self: Command<Name, Input, E, R>, shortDescription: string): Command<Name, Input, E, R>
1125
- } = dual(2, <const Name extends string, Input, E, R>(
1126
- self: Command<Name, Input, E, R>,
1286
+ <const Name extends string, Input, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>, shortDescription: string): Command<Name, Input, ContextInput, E, R>
1287
+ } = dual(2, <const Name extends string, Input, E, R, ContextInput>(
1288
+ self: Command<Name, Input, ContextInput, E, R>,
1127
1289
  shortDescription: string
1128
1290
  ) => makeCommand({ ...toImpl(self), shortDescription }))
1129
1291
 
@@ -1146,9 +1308,9 @@ export const withAlias: {
1146
1308
  * @since 4.0.0
1147
1309
  * @category combinators
1148
1310
  */
1149
- (alias: string): <const Name extends string, Input, E, R>(
1150
- self: Command<Name, Input, E, R>
1151
- ) => Command<Name, Input, E, R>
1311
+ (alias: string): <const Name extends string, Input, E, R, ContextInput>(
1312
+ self: Command<Name, Input, ContextInput, E, R>
1313
+ ) => Command<Name, Input, ContextInput, E, R>
1152
1314
  /**
1153
1315
  * Sets an alias for a command.
1154
1316
  *
@@ -1158,9 +1320,9 @@ export const withAlias: {
1158
1320
  * @since 4.0.0
1159
1321
  * @category combinators
1160
1322
  */
1161
- <const Name extends string, Input, E, R>(self: Command<Name, Input, E, R>, alias: string): Command<Name, Input, E, R>
1162
- } = dual(2, <const Name extends string, Input, E, R>(
1163
- self: Command<Name, Input, E, R>,
1323
+ <const Name extends string, Input, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>, alias: string): Command<Name, Input, ContextInput, E, R>
1324
+ } = dual(2, <const Name extends string, Input, E, R, ContextInput>(
1325
+ self: Command<Name, Input, ContextInput, E, R>,
1164
1326
  alias: string
1165
1327
  ) => makeCommand({ ...toImpl(self), alias }))
1166
1328
 
@@ -1177,22 +1339,22 @@ export const annotate: {
1177
1339
  * @since 4.0.0
1178
1340
  * @category combinators
1179
1341
  */
1180
- <I, S>(service: ServiceMap.Key<I, S>, value: NoInfer<S>): <Name extends string, Input, E, R>(
1181
- self: Command<Name, Input, E, R>
1182
- ) => Command<Name, Input, E, R>
1342
+ <I, S>(service: ServiceMap.Key<I, S>, value: NoInfer<S>): <Name extends string, Input, E, R, ContextInput>(
1343
+ self: Command<Name, Input, ContextInput, E, R>
1344
+ ) => Command<Name, Input, ContextInput, E, R>
1183
1345
  /**
1184
1346
  * Adds a custom annotation to a command.
1185
1347
  *
1186
1348
  * @since 4.0.0
1187
1349
  * @category combinators
1188
1350
  */
1189
- <Name extends string, Input, E, R, I, S>(
1190
- self: Command<Name, Input, E, R>,
1351
+ <Name extends string, Input, E, R, ContextInput, I, S>(
1352
+ self: Command<Name, Input, ContextInput, E, R>,
1191
1353
  service: ServiceMap.Key<I, S>,
1192
1354
  value: NoInfer<S>
1193
- ): Command<Name, Input, E, R>
1194
- } = dual(3, <Name extends string, Input, E, R, I, S>(
1195
- self: Command<Name, Input, E, R>,
1355
+ ): Command<Name, Input, ContextInput, E, R>
1356
+ } = dual(3, <Name extends string, Input, E, R, ContextInput, I, S>(
1357
+ self: Command<Name, Input, ContextInput, E, R>,
1196
1358
  service: ServiceMap.Key<I, S>,
1197
1359
  value: NoInfer<S>
1198
1360
  ) => {
@@ -1213,18 +1375,21 @@ export const annotateMerge: {
1213
1375
  * @since 4.0.0
1214
1376
  * @category combinators
1215
1377
  */
1216
- <I>(annotations: ServiceMap.ServiceMap<I>): <Name extends string, Input, E, R>(
1217
- self: Command<Name, Input, E, R>
1218
- ) => Command<Name, Input, E, R>
1378
+ <I>(annotations: ServiceMap.ServiceMap<I>): <Name extends string, Input, E, R, ContextInput>(
1379
+ self: Command<Name, Input, ContextInput, E, R>
1380
+ ) => Command<Name, Input, ContextInput, E, R>
1219
1381
  /**
1220
1382
  * Merges a ServiceMap of annotations into a command.
1221
1383
  *
1222
1384
  * @since 4.0.0
1223
1385
  * @category combinators
1224
1386
  */
1225
- <Name extends string, Input, E, R, I>(self: Command<Name, Input, E, R>, annotations: ServiceMap.ServiceMap<I>): Command<Name, Input, E, R>
1226
- } = dual(2, <Name extends string, Input, E, R, I>(
1227
- self: Command<Name, Input, E, R>,
1387
+ <Name extends string, Input, E, R, ContextInput, I>(
1388
+ self: Command<Name, Input, ContextInput, E, R>,
1389
+ annotations: ServiceMap.ServiceMap<I>
1390
+ ): Command<Name, Input, ContextInput, E, R>
1391
+ } = dual(2, <Name extends string, Input, E, R, ContextInput, I>(
1392
+ self: Command<Name, Input, ContextInput, E, R>,
1228
1393
  annotations: ServiceMap.ServiceMap<I>
1229
1394
  ) => {
1230
1395
  const impl = toImpl(self)
@@ -1274,9 +1439,9 @@ export const withExamples: {
1274
1439
  * @since 4.0.0
1275
1440
  * @category combinators
1276
1441
  */
1277
- (examples: ReadonlyArray<Command.Example>): <const Name extends string, Input, E, R>(
1278
- self: Command<Name, Input, E, R>
1279
- ) => Command<Name, Input, E, R>
1442
+ (examples: ReadonlyArray<Command.Example>): <const Name extends string, Input, E, R, ContextInput>(
1443
+ self: Command<Name, Input, ContextInput, E, R>
1444
+ ) => Command<Name, Input, ContextInput, E, R>
1280
1445
  /**
1281
1446
  * Sets usage examples for a command.
1282
1447
  *
@@ -1298,9 +1463,12 @@ export const withExamples: {
1298
1463
  * @since 4.0.0
1299
1464
  * @category combinators
1300
1465
  */
1301
- <const Name extends string, Input, E, R>(self: Command<Name, Input, E, R>, examples: ReadonlyArray<Command.Example>): Command<Name, Input, E, R>
1302
- } = dual(2, <const Name extends string, Input, E, R>(
1303
- self: Command<Name, Input, E, R>,
1466
+ <const Name extends string, Input, E, R, ContextInput>(
1467
+ self: Command<Name, Input, ContextInput, E, R>,
1468
+ examples: ReadonlyArray<Command.Example>
1469
+ ): Command<Name, Input, ContextInput, E, R>
1470
+ } = dual(2, <const Name extends string, Input, E, R, ContextInput>(
1471
+ self: Command<Name, Input, ContextInput, E, R>,
1304
1472
  examples: ReadonlyArray<Command.Example>
1305
1473
  ) => makeCommand({ ...toImpl(self), examples }))
1306
1474
 
@@ -1309,10 +1477,10 @@ export const withExamples: {
1309
1477
  /* ========================================================================== */
1310
1478
 
1311
1479
  // Internal helper: transforms a command's handler while preserving other properties
1312
- const mapHandler = <Name extends string, Input, E, R, E2, R2>(
1313
- self: Command<Name, Input, E, R>,
1480
+ const mapHandler = <Name extends string, Input, E, R, ContextInput, E2, R2>(
1481
+ self: Command<Name, Input, ContextInput, E, R>,
1314
1482
  f: (handler: Effect.Effect<void, E | CliError.CliError, R | Environment>, input: Input) => Effect.Effect<void, E2, R2>
1315
- ) => {
1483
+ ): Command<Name, Input, ContextInput, E2, R2> => {
1316
1484
  const impl = toImpl(self)
1317
1485
  return makeCommand({ ...impl, handle: (input, path) => f(impl.handle(input, path), input) })
1318
1486
  }
@@ -1395,9 +1563,9 @@ export const provide: {
1395
1563
  options?: {
1396
1564
  readonly local?: boolean | undefined
1397
1565
  } | undefined
1398
- ): <const Name extends string, E, R>(
1399
- self: Command<Name, Input, E, R>
1400
- ) => Command<Name, Input, E | LE, Exclude<R, LA> | LR>
1566
+ ): <const Name extends string, E, R, ContextInput>(
1567
+ self: Command<Name, Input, ContextInput, E, R>
1568
+ ) => Command<Name, Input, ContextInput, E | LE, Exclude<R, LA> | LR>
1401
1569
  /**
1402
1570
  * Provides the handler of a command with the services produced by a layer
1403
1571
  * that optionally depends on the command-line input to be created.
@@ -1434,15 +1602,15 @@ export const provide: {
1434
1602
  * @since 4.0.0
1435
1603
  * @category providing services
1436
1604
  */
1437
- <const Name extends string, Input, E, R, LA, LE, LR>(
1438
- self: Command<Name, Input, E, R>,
1605
+ <const Name extends string, Input, E, R, ContextInput, LA, LE, LR>(
1606
+ self: Command<Name, Input, ContextInput, E, R>,
1439
1607
  layer: Layer.Layer<LA, LE, LR> | ((input: Input) => Layer.Layer<LA, LE, LR>),
1440
1608
  options?: {
1441
1609
  readonly local?: boolean | undefined
1442
1610
  } | undefined
1443
- ): Command<Name, Input, E | LE, Exclude<R, LA> | LR>
1444
- } = dual((args) => isCommand(args[0]), <const Name extends string, Input, E, R, LA, LE, LR>(
1445
- self: Command<Name, Input, E, R>,
1611
+ ): Command<Name, Input, ContextInput, E | LE, Exclude<R, LA> | LR>
1612
+ } = dual((args) => isCommand(args[0]), <const Name extends string, Input, E, R, ContextInput, LA, LE, LR>(
1613
+ self: Command<Name, Input, ContextInput, E, R>,
1446
1614
  layer: Layer.Layer<LA, LE, LR> | ((input: Input) => Layer.Layer<LA, LE, LR>),
1447
1615
  options?: { readonly local?: boolean | undefined } | undefined
1448
1616
  ) =>
@@ -1466,9 +1634,9 @@ export const provideSync: {
1466
1634
  * @since 4.0.0
1467
1635
  * @category providing services
1468
1636
  */
1469
- <I, S, Input>(service: ServiceMap.Key<I, S>, implementation: S | ((input: Input) => S)): <const Name extends string, E, R>(
1470
- self: Command<Name, Input, E, R>
1471
- ) => Command<Name, Input, E, Exclude<R, I>>
1637
+ <I, S, Input>(service: ServiceMap.Key<I, S>, implementation: S | ((input: Input) => S)): <const Name extends string, E, R, ContextInput>(
1638
+ self: Command<Name, Input, ContextInput, E, R>
1639
+ ) => Command<Name, Input, ContextInput, E, Exclude<R, I>>
1472
1640
  /**
1473
1641
  * Provides the handler of a command with the implementation of a service that
1474
1642
  * optionally depends on the command-line input to be constructed.
@@ -1476,13 +1644,13 @@ export const provideSync: {
1476
1644
  * @since 4.0.0
1477
1645
  * @category providing services
1478
1646
  */
1479
- <const Name extends string, Input, E, R, I, S>(
1480
- self: Command<Name, Input, E, R>,
1647
+ <const Name extends string, Input, E, R, ContextInput, I, S>(
1648
+ self: Command<Name, Input, ContextInput, E, R>,
1481
1649
  service: ServiceMap.Key<I, S>,
1482
1650
  implementation: S | ((input: Input) => S)
1483
- ): Command<Name, Input, E, Exclude<R, I>>
1484
- } = dual(3, <const Name extends string, Input, E, R, I, S>(
1485
- self: Command<Name, Input, E, R>,
1651
+ ): Command<Name, Input, ContextInput, E, Exclude<R, I>>
1652
+ } = dual(3, <const Name extends string, Input, E, R, ContextInput, I, S>(
1653
+ self: Command<Name, Input, ContextInput, E, R>,
1486
1654
  service: ServiceMap.Key<I, S>,
1487
1655
  implementation: S | ((input: Input) => S)
1488
1656
  ) =>
@@ -1511,9 +1679,9 @@ export const provideEffect: {
1511
1679
  <I, S, Input, R2, E2>(
1512
1680
  service: ServiceMap.Key<I, S>,
1513
1681
  effect: Effect.Effect<S, E2, R2> | ((input: Input) => Effect.Effect<S, E2, R2>)
1514
- ): <const Name extends string, E, R>(
1515
- self: Command<Name, Input, E, R>
1516
- ) => Command<Name, Input, E | E2, Exclude<R, I> | R2>
1682
+ ): <const Name extends string, E, R, ContextInput>(
1683
+ self: Command<Name, Input, ContextInput, E, R>
1684
+ ) => Command<Name, Input, ContextInput, E | E2, Exclude<R, I> | R2>
1517
1685
  /**
1518
1686
  * Provides the handler of a command with the service produced by an effect
1519
1687
  * that optionally depends on the command-line input to be created.
@@ -1521,13 +1689,13 @@ export const provideEffect: {
1521
1689
  * @since 4.0.0
1522
1690
  * @category providing services
1523
1691
  */
1524
- <const Name extends string, Input, E, R, I, S, R2, E2>(
1525
- self: Command<Name, Input, E, R>,
1692
+ <const Name extends string, Input, E, R, ContextInput, I, S, R2, E2>(
1693
+ self: Command<Name, Input, ContextInput, E, R>,
1526
1694
  service: ServiceMap.Key<I, S>,
1527
1695
  effect: Effect.Effect<S, E2, R2> | ((input: Input) => Effect.Effect<S, E2, R2>)
1528
- ): Command<Name, Input, E | E2, Exclude<R, I> | R2>
1529
- } = dual(3, <const Name extends string, Input, E, R, I, S, R2, E2>(
1530
- self: Command<Name, Input, E, R>,
1696
+ ): Command<Name, Input, ContextInput, E | E2, Exclude<R, I> | R2>
1697
+ } = dual(3, <const Name extends string, Input, E, R, ContextInput, I, S, R2, E2>(
1698
+ self: Command<Name, Input, ContextInput, E, R>,
1531
1699
  service: ServiceMap.Key<I, S>,
1532
1700
  effect: Effect.Effect<S, E2, R2> | ((input: Input) => Effect.Effect<S, E2, R2>)
1533
1701
  ) =>
@@ -1554,9 +1722,9 @@ export const provideEffectDiscard: {
1554
1722
  */
1555
1723
  <_, Input, E2, R2>(
1556
1724
  effect: Effect.Effect<_, E2, R2> | ((input: Input) => Effect.Effect<_, E2, R2>)
1557
- ): <const Name extends string, E, R>(
1558
- self: Command<Name, Input, E, R>
1559
- ) => Command<Name, Input, E | E2, R | R2>
1725
+ ): <const Name extends string, E, R, ContextInput>(
1726
+ self: Command<Name, Input, ContextInput, E, R>
1727
+ ) => Command<Name, Input, ContextInput, E | E2, R | R2>
1560
1728
  /**
1561
1729
  * Allows for execution of an effect, which optionally depends on command-line
1562
1730
  * input to be created, prior to executing the handler of a command.
@@ -1564,12 +1732,12 @@ export const provideEffectDiscard: {
1564
1732
  * @since 4.0.0
1565
1733
  * @category providing services
1566
1734
  */
1567
- <const Name extends string, Input, E, R, _, E2, R2>(
1568
- self: Command<Name, Input, E, R>,
1735
+ <const Name extends string, Input, E, R, ContextInput, _, E2, R2>(
1736
+ self: Command<Name, Input, ContextInput, E, R>,
1569
1737
  effect: Effect.Effect<_, E2, R2> | ((input: Input) => Effect.Effect<_, E2, R2>)
1570
- ): Command<Name, Input, E | E2, R | R2>
1571
- } = dual(2, <const Name extends string, Input, E, R, _, E2, R2>(
1572
- self: Command<Name, Input, E, R>,
1738
+ ): Command<Name, Input, ContextInput, E | E2, R | R2>
1739
+ } = dual(2, <const Name extends string, Input, E, R, ContextInput, _, E2, R2>(
1740
+ self: Command<Name, Input, ContextInput, E, R>,
1573
1741
  effect: Effect.Effect<_, E2, R2> | ((input: Input) => Effect.Effect<_, E2, R2>)
1574
1742
  ) =>
1575
1743
  mapHandler(self, (handler, input) => Effect.andThen(typeof effect === "function" ? effect(input) : effect, handler)))
@@ -1617,17 +1785,16 @@ const getOutOfScopeGlobalFlagErrors = (
1617
1785
  return errors
1618
1786
  }
1619
1787
 
1620
- const showHelp = <Name extends string, Input, E, R>(
1621
- command: Command<Name, Input, E, R>,
1622
- commandPath: ReadonlyArray<string>,
1623
- errors?: ReadonlyArray<CliError.CliError>
1624
- ): Effect.Effect<void, never, Environment> =>
1788
+ const showHelp = <Name extends string, Input, E, R, ContextInput>(
1789
+ command: Command<Name, Input, ContextInput, E, R>,
1790
+ error: CliError.ShowHelp
1791
+ ): Effect.Effect<void, CliError.CliError, Environment> =>
1625
1792
  Effect.gen(function*() {
1626
1793
  const formatter = yield* CliOutput.Formatter
1627
- const helpDoc = yield* getHelpForCommandPath(command, commandPath, GlobalFlag.BuiltIns)
1794
+ const helpDoc = yield* getHelpForCommandPath(command, error.commandPath, GlobalFlag.BuiltIns)
1628
1795
  yield* Console.log(formatter.formatHelpDoc(helpDoc))
1629
- if (errors && errors.length > 0) {
1630
- yield* Console.error(formatter.formatErrors(errors))
1796
+ if (error.errors.length > 0) {
1797
+ yield* Console.error(formatter.formatErrors(error.errors as any))
1631
1798
  }
1632
1799
  })
1633
1800
 
@@ -1646,7 +1813,7 @@ const showHelp = <Name extends string, Input, E, R>(
1646
1813
  * yield* Console.log(`Hello, ${config.name}!`)
1647
1814
  * }))
1648
1815
  *
1649
- * // Automatically gets args from process.argv
1816
+ * // Automatically gets args from the Stdio service
1650
1817
  * const program = Command.run(greetCommand, {
1651
1818
  * version: "1.0.0"
1652
1819
  * })
@@ -1671,7 +1838,7 @@ export const run: {
1671
1838
  * yield* Console.log(`Hello, ${config.name}!`)
1672
1839
  * }))
1673
1840
  *
1674
- * // Automatically gets args from process.argv
1841
+ * // Automatically gets args from the Stdio service
1675
1842
  * const program = Command.run(greetCommand, {
1676
1843
  * version: "1.0.0"
1677
1844
  * })
@@ -1684,8 +1851,8 @@ export const run: {
1684
1851
  config: {
1685
1852
  readonly version: string
1686
1853
  }
1687
- ): <Name extends string, Input, E, R>(
1688
- command: Command<Name, Input, E, R>
1854
+ ): <Name extends string, Input, E, R, ContextInput>(
1855
+ command: Command<Name, Input, ContextInput, E, R>
1689
1856
  ) => Effect.Effect<void, E | CliError.CliError, R | Environment>
1690
1857
  /**
1691
1858
  * Runs a command with the provided input arguments.
@@ -1702,7 +1869,7 @@ export const run: {
1702
1869
  * yield* Console.log(`Hello, ${config.name}!`)
1703
1870
  * }))
1704
1871
  *
1705
- * // Automatically gets args from process.argv
1872
+ * // Automatically gets args from the Stdio service
1706
1873
  * const program = Command.run(greetCommand, {
1707
1874
  * version: "1.0.0"
1708
1875
  * })
@@ -1711,23 +1878,24 @@ export const run: {
1711
1878
  * @since 4.0.0
1712
1879
  * @category command execution
1713
1880
  */
1714
- <Name extends string, Input, E, R>(
1715
- command: Command<Name, Input, E, R>,
1881
+ <Name extends string, Input, E, R, ContextInput>(
1882
+ command: Command<Name, Input, ContextInput, E, R>,
1716
1883
  config: {
1717
1884
  readonly version: string
1718
1885
  }
1719
1886
  ): Effect.Effect<void, E | CliError.CliError, R | Environment>
1720
- } = dual(2, <Name extends string, Input, E, R>(
1721
- command: Command<Name, Input, E, R>,
1887
+ } = dual(2, <Name extends string, Input, E, R, ContextInput>(
1888
+ command: Command<Name, Input, ContextInput, E, R>,
1722
1889
  config: {
1723
1890
  readonly version: string
1724
1891
  }
1725
- ) => {
1726
- // TODO: process.argv is a Node.js global. For browser/edge runtime support,
1727
- // consider accepting an optional args parameter or using a platform service.
1728
- const input = process.argv.slice(2)
1729
- return runWith(command, config)(input)
1730
- })
1892
+ ) =>
1893
+ Stdio.Stdio.use(({ args }) =>
1894
+ Effect.flatMap(
1895
+ args,
1896
+ (args) => runWith(command, config)(args)
1897
+ )
1898
+ ))
1731
1899
 
1732
1900
  /**
1733
1901
  * Runs a command with explicitly provided arguments instead of using process.argv.
@@ -1768,8 +1936,8 @@ export const run: {
1768
1936
  * @since 4.0.0
1769
1937
  * @category command execution
1770
1938
  */
1771
- export const runWith = <const Name extends string, Input, E, R>(
1772
- command: Command<Name, Input, E, R>,
1939
+ export const runWith = <const Name extends string, Input, E, R, ContextInput>(
1940
+ command: Command<Name, Input, ContextInput, E, R>,
1773
1941
  config: {
1774
1942
  readonly version: string
1775
1943
  }
@@ -1800,7 +1968,7 @@ export const runWith = <const Name extends string, Input, E, R>(
1800
1968
  const outOfScopeErrors = getOutOfScopeGlobalFlagErrors(allFlags, activeFlags, flagMap, commandPath)
1801
1969
  if (outOfScopeErrors.length > 0) {
1802
1970
  const parseErrors = parsedArgs.errors ?? []
1803
- return yield* showHelp(command, commandPath, [...outOfScopeErrors, ...parseErrors])
1971
+ return yield* new CliError.ShowHelp({ commandPath, errors: [...outOfScopeErrors, ...parseErrors] })
1804
1972
  }
1805
1973
 
1806
1974
  // 5. Process action flags — first present action wins, then exit
@@ -1819,11 +1987,11 @@ export const runWith = <const Name extends string, Input, E, R>(
1819
1987
 
1820
1988
  // 6. Handle parsing errors
1821
1989
  if (parsedArgs.errors && parsedArgs.errors.length > 0) {
1822
- return yield* showHelp(command, commandPath, parsedArgs.errors)
1990
+ return yield* new CliError.ShowHelp({ commandPath, errors: parsedArgs.errors })
1823
1991
  }
1824
1992
  const parseResult = yield* Effect.result(commandImpl.parse(parsedArgs))
1825
1993
  if (parseResult._tag === "Failure") {
1826
- return yield* showHelp(command, commandPath, [parseResult.failure])
1994
+ return yield* new CliError.ShowHelp({ commandPath, errors: [parseResult.failure] })
1827
1995
  }
1828
1996
 
1829
1997
  // 7. Provide setting values
@@ -1847,11 +2015,11 @@ export const runWith = <const Name extends string, Input, E, R>(
1847
2015
  yield* Effect.provideServices(program, services)
1848
2016
  },
1849
2017
  Effect.catchFilter(
1850
- ((error: any) =>
2018
+ (error) =>
1851
2019
  CliError.isCliError(error) && error._tag === "ShowHelp"
1852
2020
  ? Result.succeed(error)
1853
- : Result.fail(error)) as any,
1854
- (error: any) => showHelp(command, error.commandPath)
2021
+ : Result.fail(error),
2022
+ (error) => Effect.andThen(showHelp(command, error), Effect.fail(error))
1855
2023
  ),
1856
2024
  Effect.catchFilter(
1857
2025
  (e) =>