@loomcli/core 0.7.0 → 0.8.0

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.
@@ -3,10 +3,10 @@ import type { ApplicationEnvironment, applicationEnvironment } from './environme
3
3
  import type { ExtensionValue } from './extension.js';
4
4
  import type { GlobalsState } from './globals.js';
5
5
  import type { CommandGraph } from './inspect.js';
6
- import type { BuiltPlugin, Plugin } from './plugin.js';
6
+ import type { BuiltPlugin, InstalledOptionValues, Plugin } from './plugin.js';
7
7
  import type { RenderingPolicy } from './rendering.js';
8
8
  import type { Translation, TranslatorRegistry } from './translators.js';
9
- import type { Action, ArgumentConfig, ArgumentValue, declaredTypes, DeclaredTypes, DefaultConstraint, GlobalNameConstraint, GlobalOmissionConstraint, PerValueConstraint, NameConstraint, ExitCode, OptionConfig, OptionValue, ResultViews, ResultViewsOf, RowViews, RunOptions, ValidateOmittedConstraint } from './types.js';
9
+ import type { Action, ArgumentConfig, ArgumentValue, declaredTypes, DeclaredTypes, DefaultConstraint, ImpliedConstraint, GlobalNameConstraint, GlobalOmissionConstraint, PerValueConstraint, NameConstraint, ExitCode, OptionConfig, OptionValue, ResultViews, ResultViewsOf, RowViews, RunOptions, ValidateOmittedConstraint } from './types.js';
10
10
  import type { ViewContributions, ViewOverride } from './view.js';
11
11
  /**
12
12
  * Every authoring call an Application can publish, beside `run()` and `name`, which always remain.
@@ -65,15 +65,15 @@ declare class ApplicationBuilder<Args, Options, Globals, State extends Applicati
65
65
  readonly [declaredTypes]: DeclaredTypes<Args, Options, Globals, Result>;
66
66
  constructor(name: string, declared: {
67
67
  config: ApplicationConfig;
68
- globals: GlobalsState<Globals>;
68
+ globals: GlobalsState;
69
69
  root: CommandState<Args, Options, Globals>;
70
70
  });
71
71
  get name(): string;
72
72
  argument<const Name extends string, const Config extends ArgumentConfig>(name: Name, config: Config & NameConstraint<Name> & NoInfer<DefaultConstraint<Config>> & NoInfer<PerValueConstraint<Config>> & NoInfer<ValidateOmittedConstraint<Config>>): Application<Args & Record<Name, ArgumentValue<Config>>, Options, Globals, AfterArgument<State>, Plugins, Result>;
73
- option<const Name extends string, const Config extends OptionConfig>(name: Name, config: Config & NameConstraint<Name> & GlobalNameConstraint<Name, Globals> & NoInfer<DefaultConstraint<Config>> & NoInfer<PerValueConstraint<Config>> & NoInfer<ValidateOmittedConstraint<Config>>): Application<Args, Options & Record<Name, OptionValue<Config>>, Globals, State, Plugins, Result>;
73
+ option<const Name extends string, const Config extends OptionConfig>(name: Name, config: Config & NameConstraint<Name> & GlobalNameConstraint<Name, Globals> & NoInfer<DefaultConstraint<Config>> & NoInfer<ImpliedConstraint<Config>> & NoInfer<PerValueConstraint<Config>> & NoInfer<ValidateOmittedConstraint<Config>>): Application<Args, Options & Record<Name, OptionValue<Config>>, Globals, State, Plugins, Result>;
74
74
  globalOption<const Name extends string, const Config extends OptionConfig>(name: Name, config: Config & NameConstraint<Name> & (Name extends keyof Options ? {
75
75
  'This option name is already declared as a local option': Name;
76
- } : unknown) & NoInfer<DefaultConstraint<Config>> & NoInfer<PerValueConstraint<Config>> & NoInfer<ValidateOmittedConstraint<Config>> & NoInfer<GlobalOmissionConstraint<Config>>): Application<Args, Options, Globals & Record<Name, OptionValue<Config>>, State, Plugins, Result>;
76
+ } : unknown) & NoInfer<DefaultConstraint<Config>> & NoInfer<ImpliedConstraint<Config>> & NoInfer<PerValueConstraint<Config>> & NoInfer<ValidateOmittedConstraint<Config>> & NoInfer<GlobalOmissionConstraint<Config>>): Application<Args, Options, Globals & Record<Name, OptionValue<Config>>, State, Plugins, Result>;
77
77
  /** Registering the action closes input authoring; extension configuration remains available. */
78
78
  action(handler: Action<Args, Globals & Options, Result>): Application<Args, Options, Globals, AfterAction, Plugins, Result>;
79
79
  /** A child arrives in any type state, because its own action is the call that finished it. */
@@ -133,9 +133,14 @@ declare class ApplicationBuilder<Args, Options, Globals, State extends Applicati
133
133
  * `Application<A, O, G>` accepts an application in any state, a finished one included.
134
134
  */
135
135
  export type Application<Args = {}, Options = {}, Globals = {}, State extends ApplicationMethod = AfterAction, Plugins extends readonly Plugin[] = readonly Plugin[], Result = unknown> = Pick<ApplicationBuilder<Args, Options, Globals, State, Plugins, Result>, typeof applicationEnvironment | typeof declaredTypes | 'extend' | 'inspect' | 'name' | 'run' | State | ResultMethod<Result>>;
136
+ /**
137
+ * An Application starts with the option values its installed plugins contribute as its globals,
138
+ * computed once from the constructor's `plugins`, so every action reads them typed and each
139
+ * `globalOption()` call adds its own to them.
140
+ */
136
141
  interface ApplicationConstructor {
137
142
  new (name: string): Application<{}, {}, {}, ApplicationMethod, readonly []>;
138
- new <const Plugins extends readonly Plugin[] = readonly []>(name: string, options: ApplicationOptions<Plugins>): Application<{}, {}, {}, ApplicationMethod, Plugins>;
143
+ new <const Plugins extends readonly Plugin[] = readonly []>(name: string, options: ApplicationOptions<Plugins>): Application<{}, {}, InstalledOptionValues<Plugins>, ApplicationMethod, Plugins>;
139
144
  }
140
145
  /** The core facts one Application declares, validated at construction and reported by `inspect()`. */
141
146
  interface ApplicationFacts {
@@ -21,7 +21,7 @@ import { renderingPolicy } from './rendering.js';
21
21
  import { brokenOutputView, runOptions, viewCorrection } from './rules.js';
22
22
  import { bracketRun, cancellationCode, isCancellationEcho } from './signals.js';
23
23
  import { readTranslations, translateThrow } from './translators.js';
24
- import { checkDeclarations, prepareInputs } from './validation.js';
24
+ import { checkDeclarations, prepareDeclaredValues } from './validation.js';
25
25
  import { buildViews, viewIdentities } from './view.js';
26
26
  /** The registry a failure is reported through when the application's own could not be built. */
27
27
  const noViews = [];
@@ -339,7 +339,8 @@ class ApplicationBuilder {
339
339
  inspected();
340
340
  }
341
341
  const inputs = { globals: graph.globals.inputs, locals: collectInputs(graph.root) };
342
- const defaults = await prepareInputs(inputs, host, inputPlaces(graph));
342
+ const places = inputPlaces(graph);
343
+ const declaredValues = await prepareDeclaredValues(inputs, host, places);
343
344
  graphBuilt = true;
344
345
  if (!controller.signal.aborted) {
345
346
  /**
@@ -349,12 +350,13 @@ class ApplicationBuilder {
349
350
  signals.install(ownedSignals(built.plugins));
350
351
  await runInvocation({
351
352
  channel: (binding) => invocationOutput.channel(binding),
352
- defaults,
353
+ declaredValues,
353
354
  graph,
354
355
  host,
355
356
  inspected,
356
357
  offer,
357
358
  out: output.out,
359
+ places,
358
360
  plugins: built.plugins,
359
361
  report: (fault) => faults.push(fault),
360
362
  route: (path) => {
@@ -583,7 +585,8 @@ function captureOptions(name, options) {
583
585
  * application's own view overrides, its translations, the rendering policy, the options slot and
584
586
  * its facts, the installed list and every rule between two plugins, the root's extension values,
585
587
  * and then each plugin's Commands, which attach to the root first, in installation order and list
586
- * order. Each reads the one copy of the options `captureOptions` takes.
588
+ * order. Each reads the one copy of the options `captureOptions` takes. The root's globals are
589
+ * the option values the declared `plugins` tuple contributes.
587
590
  */
588
591
  function declareApplication(name, declared) {
589
592
  const slot = captureOptions(name, declared);
@@ -651,7 +654,10 @@ function checkApplicationName(name) {
651
654
  }
652
655
  return name;
653
656
  }
654
- /** Constructor inference preserves the installed plugin tuple; globals start empty. */
657
+ /**
658
+ * Constructor inference preserves the installed plugin tuple, and the globals start as the option
659
+ * values the installed plugins contribute.
660
+ */
655
661
  class ApplicationDeclaration extends ApplicationBuilder {
656
662
  constructor(name, options) {
657
663
  // The arguments evaluate in order, so the name is checked before any option is read.
package/dist/chain.d.ts CHANGED
@@ -4,7 +4,7 @@ import type { CommandGraph, CommandNode } from './inspect.js';
4
4
  import type { BuiltPlugin, PluginOptions, PluginOptionSpellings, PluginOptionValues } from './plugin.js';
5
5
  import type { ContextualStyle } from './style.js';
6
6
  import type { ActionChannel, Host, OpenResult, Out, Request, ResultBinding } from './types.js';
7
- import type { DefaultValues } from './validation.js';
7
+ import type { InputPlaces, DeclaredValues } from './validation.js';
8
8
  /**
9
9
  * What the rest of one chain did: the action ran, a later middleware took over by returning without
10
10
  * calling its own `next()`, or the run was cancelled before the action ran.
@@ -12,17 +12,21 @@ import type { DefaultValues } from './validation.js';
12
12
  type ChainOutcome = 'cancelled' | 'dispatched' | 'taken-over';
13
13
  /**
14
14
  * What one middleware receives. `graph` is the frozen graph `inspect()` returns, built once for the
15
- * run, and `command` is the routed node inside it. `options` holds this plugin's own option values
16
- * and never another plugin's or the application's globals, and `spellings` holds the spelling that
17
- * supplied each of them as a token, which a filled or defaulted option never has. `request` is the
18
- * routed Command's invocation, parsed and validated ahead of the chain, and `null` while core holds
19
- * a fault and on a group. `view` names the view the result renders through: it reads as the
20
- * declaration's default until a middleware assigns one, and as `null` on a Command that declares
21
- * none. The last assignment before the dispatch boundary wins, and one made after it changes
22
- * nothing.
15
+ * run, and `command` is the routed node inside it. `options` holds the validated value of every
16
+ * global option, the application's and every plugin's, keyed by declared name: the plugin's own
17
+ * options are typed from its declaration and every other key reads `unknown`, because a plugin
18
+ * compiles without the Application that installs it. It is `null` when a global option has a
19
+ * structural fault or was rejected, so a middleware never reads a global value no validator
20
+ * accepted, and a fault on a local option alone leaves it set. `spellings` holds the spelling that
21
+ * supplied each of the plugin's own options as a token, which a filled or defaulted option never
22
+ * has. `request` is the routed Command's invocation, parsed and validated ahead of the chain, and
23
+ * `null` while core holds a fault and on a group. `view` names the view the result renders
24
+ * through: it reads as the declaration's default until a middleware assigns one, and as `null` on
25
+ * a Command that declares none. The last assignment before the dispatch boundary wins, and one
26
+ * made after it changes nothing.
23
27
  */
24
28
  interface MiddlewareContext<Options extends PluginOptions = PluginOptions> {
25
- readonly options: PluginOptionValues<Options>;
29
+ readonly options: (PluginOptionValues<Options> & Readonly<Record<string, unknown>>) | null;
26
30
  readonly spellings: PluginOptionSpellings<Options>;
27
31
  readonly graph: CommandGraph;
28
32
  readonly command: CommandNode;
@@ -34,12 +38,14 @@ interface MiddlewareContext<Options extends PluginOptions = PluginOptions> {
34
38
  readonly signal: AbortSignal;
35
39
  readonly next: () => Promise<ChainOutcome>;
36
40
  }
37
- /** Everything one invocation needs after its graph is built and its defaults are validated. */
41
+ /**
42
+ * Everything one invocation needs after its graph is built and its defaults and implied values are
43
+ * validated.
44
+ */
38
45
  interface Invocation {
39
46
  style: ContextualStyle;
40
47
  /** The action's own channel, built from the routed Command's declaration when it dispatches. */
41
48
  channel: (binding: ResultBinding) => ActionChannel;
42
- defaults: DefaultValues;
43
49
  graph: BuiltGraph;
44
50
  host: Host;
45
51
  /**
@@ -60,7 +66,11 @@ interface Invocation {
60
66
  out: Out<OpenResult>;
61
67
  /** The channel a configuration source receives, whose results call names the source. */
62
68
  sourceOut: Out<OpenResult>;
69
+ /** Where every input of the graph was declared, which a broken validator's finding rebuilds. */
70
+ places: InputPlaces;
63
71
  plugins: readonly BuiltPlugin[];
72
+ /** Every declared default and implied value, validated before any token was read. */
73
+ declaredValues: DeclaredValues;
64
74
  /** A fault reported after the primary outcome, which turns a would-be 0 into 1. */
65
75
  report: (fault: LoomError) => void;
66
76
  /**
@@ -71,11 +81,12 @@ interface Invocation {
71
81
  signal: AbortSignal;
72
82
  }
73
83
  /**
74
- * Runs one invocation: the global pre-scan, routing, the dispatch this invocation prepares, and the
75
- * middleware chain it then runs. Local parsing and validation run ahead of the chain so that a
76
- * middleware reads the request, and the fault they find is held until the dispatch boundary. A
77
- * middleware that returns without calling `next()` has taken over, so the held fault is never
78
- * raised and nothing later in the chain runs.
84
+ * Runs one invocation: routing on the global options and a parent's own options, the routed
85
+ * Command's words read against its table, the dispatch this invocation prepares, and the
86
+ * middleware chain it then runs. Only an unknown Command is raised before the chain. Parsing and validation run ahead of the chain so
87
+ * that a middleware reads the request, and every other fault they find is held until the dispatch
88
+ * boundary. A middleware that returns without calling `next()` has taken over, so the held fault is
89
+ * never raised and nothing later in the chain runs.
79
90
  */
80
91
  declare function runInvocation(invocation: Invocation): Promise<void>;
81
92
  export type { ChainOutcome, Invocation, MiddlewareContext };
package/dist/chain.js CHANGED
@@ -1,8 +1,9 @@
1
- import { prepareDispatch, routeInvocation } from './command.js';
1
+ import { prepareDispatch } from './command.js';
2
2
  import { foreignFailure, InternalError, routedSubject } from './errors.js';
3
3
  import { nodeAt } from './inspect.js';
4
4
  import { isSupplied } from './options.js';
5
- import { loadDefault, pluginSentence, pluginSpellings, pluginValues } from './plugin.js';
5
+ import { parseInvocation } from './parse.js';
6
+ import { loadDefault, pluginSentence, pluginSpellings } from './plugin.js';
6
7
  import { nextMisuse, viewSelection, viewSelectionCorrection } from './rules.js';
7
8
  /**
8
9
  * The view one run selects, which is one value whichever middleware wrote it. The assignment is
@@ -96,7 +97,6 @@ function activatedEntries(plugins, values) {
96
97
  identity: installed.identity,
97
98
  // Activation proved the middleware exists, so the empty loader is never the one core calls.
98
99
  load: installed.middleware?.load ?? (() => undefined),
99
- options: pluginValues(installed.inputs, values),
100
100
  spellings: pluginSpellings(installed.inputs, values),
101
101
  }));
102
102
  }
@@ -276,7 +276,7 @@ async function runChain(invocation, routed, prepared) {
276
276
  graph,
277
277
  host: invocation.host,
278
278
  next,
279
- options: entry.options,
279
+ options: prepared.options,
280
280
  out: invocation.out,
281
281
  request: prepared.request,
282
282
  signal: invocation.signal,
@@ -312,14 +312,15 @@ async function runChain(invocation, routed, prepared) {
312
312
  return run.raised;
313
313
  }
314
314
  /**
315
- * Runs one invocation: the global pre-scan, routing, the dispatch this invocation prepares, and the
316
- * middleware chain it then runs. Local parsing and validation run ahead of the chain so that a
317
- * middleware reads the request, and the fault they find is held until the dispatch boundary. A
318
- * middleware that returns without calling `next()` has taken over, so the held fault is never
319
- * raised and nothing later in the chain runs.
315
+ * Runs one invocation: routing on the global options and a parent's own options, the routed
316
+ * Command's words read against its table, the dispatch this invocation prepares, and the
317
+ * middleware chain it then runs. Only an unknown Command is raised before the chain. Parsing and validation run ahead of the chain so
318
+ * that a middleware reads the request, and every other fault they find is held until the dispatch
319
+ * boundary. A middleware that returns without calling `next()` has taken over, so the held fault is
320
+ * never raised and nothing later in the chain runs.
320
321
  */
321
322
  async function runInvocation(invocation) {
322
- const routed = routeInvocation(invocation.graph, invocation.host.argv, invocation.route);
323
+ const routed = parseInvocation(invocation.graph, invocation.host.argv, invocation.route);
323
324
  const prepared = await prepareDispatch(invocation.graph, routed, invocation);
324
325
  let raised = undefined;
325
326
  try {
@@ -18,7 +18,7 @@ declare const variadicArgumentLast: import("./diagnostic-text.js").DiagnosticRul
18
18
  declare const optionalArgumentLast: import("./diagnostic-text.js").DiagnosticRule;
19
19
  /** An `alias()` call that names no alias. */
20
20
  declare const aliasWithoutNames: import("./diagnostic-text.js").DiagnosticRule;
21
- /** An alias that repeats its own Command's name or another of its aliases. */
21
+ /** An alias that repeats its own Command's or option's name or another of its aliases. */
22
22
  declare const repeatedAlias: import("./diagnostic-text.js").DiagnosticRule;
23
23
  /** A child whose name or alias repeats a sibling's name or alias. */
24
24
  declare const siblingNameTaken: import("./diagnostic-text.js").DiagnosticRule;
@@ -54,9 +54,9 @@ const aliasWithoutNames = registerRule('@loomcli/core/alias-without-names', {
54
54
  explanation: 'alias() adds each name it receives to the names that route to its Command, so a call with none adds nothing.',
55
55
  headline: 'Alias with no names',
56
56
  });
57
- /** An alias that repeats its own Command's name or another of its aliases. */
57
+ /** An alias that repeats its own Command's or option's name or another of its aliases. */
58
58
  const repeatedAlias = registerRule('@loomcli/core/repeated-alias', {
59
- explanation: 'A Command answers to its name and to each of its aliases, so an alias that repeats one of them routes nothing new.',
59
+ explanation: 'A Command or an option answers to its name and to each of its aliases, so an alias that repeats one of them adds nothing new.',
60
60
  headline: 'Alias repeats a name',
61
61
  });
62
62
  /** A child whose name or alias repeats a sibling's name or alias. */
package/dist/command.d.ts CHANGED
@@ -4,12 +4,12 @@ import type { LoomError } from './errors.js';
4
4
  import type { AdmittedDescriptor, DescriptorRegistry, ExtensionRecords, ExtensionStore, ExtensionSubject, ExtensionValue } from './extension.js';
5
5
  import type { BuiltGlobals, GlobalsState, GlobalTable, InputRecords } from './globals.js';
6
6
  import type { CommandGraph, CommandNode } from './inspect.js';
7
- import { compileOptions } from './options.js';
8
- import type { OptionValues } from './options.js';
7
+ import type { OptionValues, SpellingTable } from './options.js';
8
+ import type { ParsedInvocation } from './parse.js';
9
9
  import type { BuiltPlugin } from './plugin.js';
10
10
  import type { ContextualStyle } from './style.js';
11
- import type { Action, ActionChannel, ArgumentConfig, ArgumentValue, declaredTypes, DeclaredResult, DeclaredTypes, DefaultConstraint, GlobalNameConstraint, Host, PerValueConstraint, NameConstraint, OpenResult, OptionConfig, OptionValue, Out, Request, ResultBinding, ResultViews, ResultViewsOf, RowViews, ValidateOmittedConstraint } from './types.js';
12
- import type { ArgumentInput, DefaultValues, InputPlaces, InputDeclaration, OptionInput, ValidatedInputs } from './validation.js';
11
+ import type { Action, ActionChannel, ArgumentConfig, ArgumentValue, declaredTypes, DeclaredResult, DeclaredTypes, DefaultConstraint, ImpliedConstraint, GlobalNameConstraint, Host, PerValueConstraint, NameConstraint, OpenResult, OptionConfig, OptionValue, Out, Request, ResultBinding, ResultViews, ResultViewsOf, RowViews, ValidateOmittedConstraint } from './types.js';
12
+ import type { ArgumentInput, InputPlaces, InputDeclaration, OptionInput, DeclaredValues, ValidatedInputs } from './validation.js';
13
13
  /** One positional slot: the declaration it fills and whether it takes the remaining tokens. */
14
14
  export interface ArgumentSlot {
15
15
  input: InputDeclaration;
@@ -58,7 +58,12 @@ export interface BuiltCommand {
58
58
  hidden: boolean;
59
59
  inputs: readonly InputDeclaration[];
60
60
  name: string | null;
61
- options: ReturnType<typeof compileOptions>;
61
+ /**
62
+ * The one table the parser reads this Command's words against, built after every lifecycle hook
63
+ * ran: its own options, hook-declared ones included, and every global option. Each entry names
64
+ * one declaration, so a group's table holds the global options alone.
65
+ */
66
+ table: SpellingTable;
62
67
  /** The result the Command declares, or nothing where it declares none. */
63
68
  /** The built declaration is the shape the write site reads, so the channel carries it. */
64
69
  result: DeclaredResult | undefined;
@@ -290,14 +295,14 @@ export interface BuiltGraph {
290
295
  * The globals table compiles once per build and the whole graph shares it. The root's registry
291
296
  * holds every descriptor the Application names, so a hook's `extend()` call meets all of them.
292
297
  */
293
- export declare function buildGraph<Args, Options, Globals>(root: CommandState<Args, Options, Globals>, globals: GlobalsState<Globals>, plugins: readonly BuiltPlugin[]): BuiltGraph;
298
+ export declare function buildGraph<Args, Options, Globals>(root: CommandState<Args, Options, Globals>, globals: GlobalsState, plugins: readonly BuiltPlugin[]): BuiltGraph;
294
299
  export declare class CommandBuilder<Args, Options, Globals, State extends CommandMethod = CommandMethod, Result = unknown> {
295
300
  #private;
296
301
  readonly [commandValue]: true;
297
302
  readonly [declaredTypes]: DeclaredTypes<Args, Options, Globals, Result>;
298
303
  constructor(name: string, state: CommandState<Args, Options, Globals>);
299
304
  argument<const Name extends string, const Config extends ArgumentConfig>(name: Name, config: Config & NameConstraint<Name> & NoInfer<DefaultConstraint<Config>> & NoInfer<PerValueConstraint<Config>> & NoInfer<ValidateOmittedConstraint<Config>>): Command<Args & Record<Name, ArgumentValue<Config>>, Options, Globals, AfterArgument<State>, Result>;
300
- option<const Name extends string, const Config extends OptionConfig>(name: Name, config: Config & NameConstraint<Name> & GlobalNameConstraint<Name, Globals> & NoInfer<DefaultConstraint<Config>> & NoInfer<PerValueConstraint<Config>> & NoInfer<ValidateOmittedConstraint<Config>>): Command<Args, Options & Record<Name, OptionValue<Config>>, Globals, State, Result>;
305
+ option<const Name extends string, const Config extends OptionConfig>(name: Name, config: Config & NameConstraint<Name> & GlobalNameConstraint<Name, Globals> & NoInfer<DefaultConstraint<Config>> & NoInfer<ImpliedConstraint<Config>> & NoInfer<PerValueConstraint<Config>> & NoInfer<ValidateOmittedConstraint<Config>>): Command<Args, Options & Record<Name, OptionValue<Config>>, Globals, State, Result>;
301
306
  /**
302
307
  * Aliases are other portable names that route to this Command. They invalidate no call, and the
303
308
  * tuple rest parameter rejects a call that names none.
@@ -369,48 +374,20 @@ export declare const Command: CommandConstructor;
369
374
  /** Every declaration in the graph, so defaults are validated before any token is read. */
370
375
  export declare function collectInputs(command: BuiltCommand): InputDeclaration[];
371
376
  /**
372
- * Where every input of one graph was declared: each global option at its `globalOption()` call,
373
- * and each Command's own inputs at their calls on the Command, under its path from the root.
377
+ * Where every input of one graph was declared: each global option at its `globalOption()` call or
378
+ * in its plugin's `options` record, and each Command's own inputs at their calls on the Command,
379
+ * under its path from the root.
374
380
  */
375
381
  export declare function inputPlaces(graph: BuiltGraph): InputPlaces;
376
- /**
377
- * Whether a token names one of the Command's children: the Command has children and the token is
378
- * no option token. Routing and `locate` read a bare word through this rule.
379
- */
380
- export declare function readsAsChild(command: BuiltCommand, token: string): boolean;
381
- /**
382
- * Bare tokens, names or aliases, select children until a Command has none; a hyphen commits.
383
- * `walked` receives the path after each name routes, so an unknown Command leaves its caller
384
- * holding the partial path walked before it.
385
- */
386
- export declare function route(root: BuiltCommand, tokens: readonly string[], walked?: (path: readonly string[]) => void): {
387
- command: BuiltCommand;
388
- path: string[];
389
- tokens: string[];
390
- };
391
- /**
392
- * The slot the positional at one index fills: the slot at that index, else a variadic last slot,
393
- * which accepts every later positional, else none. Binding and `locate` read positions through it.
394
- */
395
- export declare function argumentSlot(slots: readonly ArgumentSlot[], position: number): ArgumentSlot | undefined;
396
- /** One invocation after the pre-scan and routing, which the middleware chain runs on top of. */
397
- export interface RoutedInvocation {
398
- command: BuiltCommand;
399
- path: readonly string[];
400
- scan: OptionValues;
401
- tokens: readonly string[];
402
- }
403
- /**
404
- * Consumes the globals table, then routes the remaining bare tokens to a Command. `walked`
405
- * receives the path as routing extends it, the partial path of an unknown Command included.
406
- */
407
- export declare function routeInvocation(graph: BuiltGraph, argv: readonly string[], walked: (path: readonly string[]) => void): RoutedInvocation;
408
382
  /** What one invocation reaches the middleware chain with. */
409
383
  export interface DispatchInvocation {
410
384
  /** The channel the action receives, which the results lane builds from the routed node. */
411
385
  channel: (binding: ResultBinding) => ActionChannel;
412
- defaults: DefaultValues;
413
386
  host: Host;
387
+ /** Where every input of the graph was declared, which a broken validator's finding rebuilds. */
388
+ places: InputPlaces;
389
+ /** Every declared default and implied value, validated before any token was read. */
390
+ declaredValues: DeclaredValues;
414
391
  /** The graph `inspect()` returns for the run, built on its first read, which a source reads. */
415
392
  inspected: () => CommandGraph;
416
393
  /** Offers a configuration source's foreign throw to the translators where its call settles. */
@@ -425,11 +402,14 @@ export interface DispatchInvocation {
425
402
  * reads and the call that dispatches; `'held'` carries the fault this phase found, which core
426
403
  * raises at the dispatch boundary and never before, so a takeover swallows it. `result` is what the
427
404
  * routed Command declared, whose views a middleware selects among, on either shape. `globals` holds
428
- * the globals table's values after the input-source stage, which activation and every plugin's own
429
- * options read on either shape.
405
+ * the globals table's values after the input-source stage, which activation and each plugin's
406
+ * spellings read on either shape. `options` is every global option's validated value, which every
407
+ * middleware reads, or `null` when a global option has a structural fault or was rejected, or the
408
+ * values could not be read.
430
409
  */
431
410
  export type Prepared = {
432
411
  globals: OptionValues;
412
+ options: Readonly<Record<string, unknown>> | null;
433
413
  result: DeclaredResult | undefined;
434
414
  } & ({
435
415
  dispatch: (view: string | null) => Promise<void>;
@@ -443,8 +423,12 @@ export type Prepared = {
443
423
  /**
444
424
  * Prepares one dispatch ahead of the middleware chain and holds whatever fault it found, so a
445
425
  * middleware reads the request before the action runs and a takeover never observes the fault.
446
- * The phases run in order: local parsing, the input-source stage, and validation. A local fault
447
- * outranks a configuration source's fault, and after either one core runs no validation.
426
+ * The phases run in order: the structural fault parsing held, a group's missing subcommand, the
427
+ * input-source stage, and validation. Either of the first two outranks a configuration source's
428
+ * fault, and a source's fault takes the place of every validation problem. Validation checks the
429
+ * global options whatever was held, so a middleware reads them after a local fault; a structural
430
+ * fault on a global option, a rejected global option, a source's fault, or a validator's own fault
431
+ * leaves `options` `null`.
448
432
  */
449
- export declare function prepareDispatch(graph: BuiltGraph, routed: RoutedInvocation, invocation: DispatchInvocation): Promise<Prepared>;
433
+ export declare function prepareDispatch(graph: BuiltGraph, routed: ParsedInvocation, invocation: DispatchInvocation): Promise<Prepared>;
450
434
  export {};