@effected/cli 0.25.0 → 0.27.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.
- package/README.md +5 -208
- package/bin/effected.js +7 -0
- package/commands/root.js +14 -0
- package/commands/schema/LiveProgress.js +114 -0
- package/commands/schema/build.js +9 -0
- package/commands/schema/check.js +12 -0
- package/commands/schema/errors.js +121 -0
- package/commands/schema/execute.js +141 -0
- package/commands/schema/flags.js +24 -0
- package/commands/schema/index.js +14 -0
- package/commands/schema/validate.js +58 -0
- package/index.d.ts +85 -3906
- package/index.js +4 -26
- package/main.d.ts +51 -0
- package/main.js +61 -0
- package/package.json +18 -50
- package/render/DiffDoc.js +51 -0
- package/tsdoc-metadata.json +1 -1
- package/version.js +11 -0
- package/Cancelled.js +0 -43
- package/CliAudience.js +0 -177
- package/CliColor.js +0 -59
- package/CliEnv.js +0 -101
- package/CliExit.js +0 -64
- package/CliFailure.js +0 -287
- package/CliFormat.js +0 -124
- package/CliInteractive.js +0 -94
- package/CliLinks.js +0 -153
- package/CliLog.js +0 -367
- package/CliLogger.js +0 -91
- package/CliMessage.js +0 -79
- package/CliPrompt.js +0 -110
- package/CliRuntime.js +0 -254
- package/CliTest.js +0 -206
- package/CliTheme.js +0 -142
- package/ConfigIssueRenderer.js +0 -63
- package/Doc.js +0 -548
- package/Fmt.js +0 -335
- package/GithubAnnotation.js +0 -39
- package/Glyphs.js +0 -82
- package/NotInteractive.js +0 -41
- package/Render.js +0 -280
- package/SchemaIssueRenderer.js +0 -47
- package/Status.js +0 -165
- package/TestTerminal.js +0 -101
- package/Token.js +0 -68
- package/internal/ExitRequested.js +0 -21
- package/internal/HelpRouting.js +0 -35
- package/internal/ansi.js +0 -229
- package/internal/autoFormat.js +0 -33
- package/internal/canPrompt.js +0 -14
- package/internal/counts.js +0 -83
- package/internal/diagnostics.js +0 -31
- package/internal/displayPath.js +0 -46
- package/internal/displayWidth.js +0 -42
- package/internal/failureTarget.js +0 -195
- package/internal/fallbackAnswer.js +0 -17
- package/internal/fileSink.js +0 -61
- package/internal/format.js +0 -175
- package/internal/inspect.js +0 -40
- package/internal/isExitCode.js +0 -11
- package/internal/layout.js +0 -249
- package/internal/linkScheme.js +0 -29
- package/internal/linkTarget.js +0 -49
- package/internal/logSafety.js +0 -45
- package/internal/renderAnsi.js +0 -51
- package/internal/renderDoc.js +0 -322
- package/internal/renderGithubLog.js +0 -59
- package/internal/renderMarkdown.js +0 -367
- package/internal/renderPlain.js +0 -49
- package/internal/scanAudience.js +0 -105
- package/internal/splitFrame.js +0 -55
- package/internal/terminalCapabilities.js +0 -23
- package/internal/wizardGate.js +0 -17
- package/testing.d.ts +0 -246
- package/testing.js +0 -4
- package/ui/CliUi.js +0 -507
- package/ui/CliUiDetached.js +0 -36
- package/ui/CliUiLive.js +0 -436
- package/ui/CliUiRouteStream.js +0 -72
- package/ui/Confirm.js +0 -244
- package/ui/DocView.js +0 -76
- package/ui/KeyHelp.js +0 -61
- package/ui/KeyTable.js +0 -198
- package/ui/MultiSelect.js +0 -259
- package/ui/Select.js +0 -229
- package/ui/Tabs.js +0 -201
- package/ui/TextInput.js +0 -289
- package/ui/Toggle.js +0 -31
- package/ui/UiKey.js +0 -48
- package/ui/UiProvider.js +0 -62
- package/ui/UiStreams.js +0 -17
- package/ui/UiTheme.js +0 -147
- package/ui/Viewport.js +0 -203
- package/ui/internal/ErrorBoundary.js +0 -29
- package/ui/internal/Holder.js +0 -73
- package/ui/internal/ScreenContext.js +0 -51
- package/ui/internal/UiProviders.js +0 -38
- package/ui/internal/ink.js +0 -121
- package/ui/internal/inkChalk.js +0 -47
- package/ui/internal/inkConsole.js +0 -150
- package/ui/internal/lazyView.js +0 -73
- package/ui/internal/lineRouter.js +0 -70
- package/ui/internal/lineText.js +0 -18
- package/ui/internal/mountPermit.js +0 -15
- package/ui/internal/processStreams.js +0 -18
- package/ui/internal/renderOptions.js +0 -12
- package/ui/testing/CliUiTest.js +0 -792
- package/ui/testing/fakeStreams.js +0 -104
- package/ui/testing/terminalModel.js +0 -67
- package/ui-testing-serializer.d.ts +0 -12
- package/ui-testing-serializer.js +0 -32
- package/ui-testing.d.ts +0 -558
- package/ui-testing.js +0 -3
- package/ui.d.ts +0 -1990
- package/ui.js +0 -17
package/CliTheme.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { Glyphs } from "./Glyphs.js";
|
|
2
|
-
import { openSequence, paintStyle } from "./internal/ansi.js";
|
|
3
|
-
import { Token } from "./Token.js";
|
|
4
|
-
import { Config, Context, Effect, Layer, Option } from "effect";
|
|
5
|
-
import { TerminalEnv } from "@effected/env";
|
|
6
|
-
import { Prompt } from "effect/cli";
|
|
7
|
-
|
|
8
|
-
// src/CliTheme.ts
|
|
9
|
-
/**
|
|
10
|
-
* A stream theme at `color`, over a style resolution and a glyph set: the one way a {@link StreamTheme} is built.
|
|
11
|
-
*
|
|
12
|
-
* @internal
|
|
13
|
-
*/
|
|
14
|
-
const streamThemeAt = (resolve, glyphs, color) => {
|
|
15
|
-
const paint = (token, text) => paintStyle(resolve(token), color, text);
|
|
16
|
-
return {
|
|
17
|
-
paint,
|
|
18
|
-
style: resolve,
|
|
19
|
-
sgr: (token) => openSequence(resolve(token), color),
|
|
20
|
-
glyphs,
|
|
21
|
-
color,
|
|
22
|
-
status: (vocab, name, text) => {
|
|
23
|
-
const glyph = paint(vocab.def(name).token, vocab.glyph(name, glyphs));
|
|
24
|
-
return text === void 0 || text === "" ? glyph : `${glyph} ${text}`;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
/** The audience rule, shared by `CliTheme.forAudience` and the class's own docs. */
|
|
29
|
-
const forAudience = (theme, audience) => audience === "agent" && theme.color !== "none" ? streamThemeAt(theme.style, theme.glyphs, "none") : theme;
|
|
30
|
-
const make = (colors, glyphs, overrides) => {
|
|
31
|
-
const resolve = (token) => Token.resolve(token, overrides);
|
|
32
|
-
const stdout = streamThemeAt(resolve, glyphs, colors.stdout);
|
|
33
|
-
const stderr = streamThemeAt(resolve, glyphs, colors.stderr);
|
|
34
|
-
return {
|
|
35
|
-
...stdout,
|
|
36
|
-
forStream: (stream) => stream === "stdout" ? stdout : stderr
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
/** The prompt glyphs that differ under ASCII; `Prompt.makeTheme` already holds the Unicode ones. */
|
|
40
|
-
const ASCII_PROMPT_GLYPHS = {
|
|
41
|
-
prefix: "?",
|
|
42
|
-
arrowUp: "^",
|
|
43
|
-
arrowDown: "v",
|
|
44
|
-
checkboxOn: "[x]",
|
|
45
|
-
checkboxOff: "[ ]",
|
|
46
|
-
tick: "+",
|
|
47
|
-
pointerSmall: ">",
|
|
48
|
-
pointer: ">"
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* The presentation of a CLI: colour tokens, glyphs and statuses, decided once from the terminal.
|
|
52
|
-
*
|
|
53
|
-
* @remarks
|
|
54
|
-
* A `Context.Service`, not a `Reference`. A colour level is a fact about the terminal, not a preference with a
|
|
55
|
-
* safe default, so there is nothing sensible for an unprovided theme to read; requiring it puts `CliTheme` in
|
|
56
|
-
* `R` and a program that forgot to wire it fails to compile rather than printing plain text to a colour
|
|
57
|
-
* terminal. {@link CliTheme.layer} reads `TerminalEnv`.
|
|
58
|
-
*
|
|
59
|
-
* @public
|
|
60
|
-
*/
|
|
61
|
-
var CliTheme = class CliTheme extends Context.Service()("@effected/cli/CliTheme") {
|
|
62
|
-
/**
|
|
63
|
-
* The theme for the terminal `TerminalEnv` describes.
|
|
64
|
-
*
|
|
65
|
-
* @remarks
|
|
66
|
-
* Bind the layer to a constant and provide it once. With `glyphs: "auto"` the glyph set is ASCII only when
|
|
67
|
-
* `TERM=dumb`, read through `Config`.
|
|
68
|
-
*
|
|
69
|
-
* @param options - token overrides and the glyph set
|
|
70
|
-
*/
|
|
71
|
-
static layer = (options) => Layer.effect(CliTheme, Effect.gen(function* () {
|
|
72
|
-
const terminal = yield* TerminalEnv;
|
|
73
|
-
const choice = options?.glyphs ?? "auto";
|
|
74
|
-
const term = choice === "auto" ? Option.getOrUndefined(yield* Config.option(Config.String("TERM")).pipe(Effect.orElseSucceed(() => Option.none()))) : void 0;
|
|
75
|
-
const glyphs = Glyphs.select({
|
|
76
|
-
ascii: choice === "ascii" ? true : choice === "unicode" ? false : "auto",
|
|
77
|
-
...term === void 0 ? {} : { term }
|
|
78
|
-
});
|
|
79
|
-
return make({
|
|
80
|
-
stdout: terminal.stdout.color,
|
|
81
|
-
stderr: terminal.stderr.color
|
|
82
|
-
}, glyphs, options?.tokens);
|
|
83
|
-
}));
|
|
84
|
-
/**
|
|
85
|
-
* The theme an audience sees of `theme`: for an agent, the same theme at colour `none` (`paint` the identity, `sgr`
|
|
86
|
-
* empty, `status` unpainted), whatever the terminal could do, because an agent never gets an escape of any kind; for
|
|
87
|
-
* anyone else, or when the audience is not known, `theme` itself.
|
|
88
|
-
*
|
|
89
|
-
* @remarks
|
|
90
|
-
* The one rule the kit applies wherever it paints for an audience: `Render.context` takes its colour and `paint`
|
|
91
|
-
* from it, `CliMessage` and `CliLog.status` paint their glyphs through it, and `./ui` gives it to the trees it
|
|
92
|
-
* mounts, so `useTheme`, `Styled` and the widgets' colour-`none` text markers all agree. A program that paints its
|
|
93
|
-
* own lines applies the same rule with it rather than re-implementing it:
|
|
94
|
-
*
|
|
95
|
-
* ```ts
|
|
96
|
-
* const line = Effect.gen(function* () {
|
|
97
|
-
* const theme = CliTheme.forAudience((yield* CliTheme).forStream("stdout"), (yield* Audience).kind)
|
|
98
|
-
* return theme.status(Status.core, "success", Fmt.sanitize(name))
|
|
99
|
-
* })
|
|
100
|
-
* ```
|
|
101
|
-
*
|
|
102
|
-
* Pure: it reads nothing, so the audience is the caller's to pass, `undefined` when it is not known.
|
|
103
|
-
*
|
|
104
|
-
* @param theme - a stream's theme, such as `CliTheme.forStream("stdout")`
|
|
105
|
-
* @param audience - who the output is for, or `undefined` when that is not known
|
|
106
|
-
*/
|
|
107
|
-
static forAudience = forAudience;
|
|
108
|
-
/**
|
|
109
|
-
* A fixed theme that needs nothing; `none` colour and Unicode glyphs unless told otherwise.
|
|
110
|
-
*
|
|
111
|
-
* @param options - the colour level and glyph set
|
|
112
|
-
*/
|
|
113
|
-
static layerTest = (options) => Layer.succeed(CliTheme, make({
|
|
114
|
-
stdout: options?.color ?? "none",
|
|
115
|
-
stderr: options?.stderrColor ?? options?.color ?? "none"
|
|
116
|
-
}, options?.glyphs === "ascii" ? Glyphs.ascii : Glyphs.unicode, void 0));
|
|
117
|
-
/**
|
|
118
|
-
* Sets core's `Prompt.Theme` from the tokens, so built-in prompts match the rest of the output.
|
|
119
|
-
*
|
|
120
|
-
* @remarks
|
|
121
|
-
* The colour fields are raw SGR openers and are empty strings when colour is `none`, and `colors` is the theme's
|
|
122
|
-
* own decision (`false` at `none`), so core's prompts and its command wizard write no colour or style escape, not
|
|
123
|
-
* even a reset, and core never re-reads the host for `NO_COLOR` or a TTY. Cursor and redraw controls are still
|
|
124
|
-
* written, whatever the theme says. Under ASCII glyphs the prompt symbols fall back to ASCII too.
|
|
125
|
-
*/
|
|
126
|
-
static promptTheme = Layer.effect(Prompt.Theme, Effect.gen(function* () {
|
|
127
|
-
const theme = yield* CliTheme;
|
|
128
|
-
const open = (token) => theme.sgr(token);
|
|
129
|
-
return Prompt.makeTheme({
|
|
130
|
-
...theme.glyphs.kind === "ascii" ? ASCII_PROMPT_GLYPHS : {},
|
|
131
|
-
ellipsis: theme.glyphs.ellipsis,
|
|
132
|
-
colors: theme.color !== "none",
|
|
133
|
-
primaryColor: open("accent"),
|
|
134
|
-
mutedColor: open("muted"),
|
|
135
|
-
successColor: open("success"),
|
|
136
|
-
errorColor: open("error"),
|
|
137
|
-
submittedColor: open("emphasis")
|
|
138
|
-
});
|
|
139
|
-
}));
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
export { CliTheme, streamThemeAt };
|
package/ConfigIssueRenderer.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { formatIssueWithHints } from "./internal/format.js";
|
|
2
|
-
|
|
3
|
-
// src/ConfigIssueRenderer.ts
|
|
4
|
-
/**
|
|
5
|
-
* Turns a `@effected/config-file` `ConfigValidationError` into one line per rejected value.
|
|
6
|
-
*
|
|
7
|
-
* @remarks
|
|
8
|
-
* `ConfigValidationError` carries the structured `issue` tree rather than a
|
|
9
|
-
* string, so a caller holds a tree it has to turn into sentences. This is that
|
|
10
|
-
* step, the same treatment {@link SchemaIssueRenderer} gives a bare issue.
|
|
11
|
-
*
|
|
12
|
-
* `ConfigValidationError.message` names the file but not the value, and the
|
|
13
|
-
* value is the diagnostic: printing only the message tells a user their config
|
|
14
|
-
* is invalid without saying which value is wrong or how it is shaped.
|
|
15
|
-
*
|
|
16
|
-
* `@effected/config-file` is an optional peer, and this module only
|
|
17
|
-
* `import type`s it, so the import is erased at build time. A consumer without
|
|
18
|
-
* the package installed can import this module without the resolver being asked
|
|
19
|
-
* for it.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```ts
|
|
23
|
-
* import { ConfigIssueRenderer } from "@effected/cli"
|
|
24
|
-
* import { Effect } from "effect"
|
|
25
|
-
*
|
|
26
|
-
* const load = configFile.load.pipe(
|
|
27
|
-
* Effect.catchTag("ConfigValidationError", (error) =>
|
|
28
|
-
* Effect.gen(function* () {
|
|
29
|
-
* yield* Effect.logError(String(error))
|
|
30
|
-
* for (const line of ConfigIssueRenderer.render(error)) yield* Effect.logError(` ${line}`)
|
|
31
|
-
* }),
|
|
32
|
-
* ),
|
|
33
|
-
* )
|
|
34
|
-
* ```
|
|
35
|
-
*
|
|
36
|
-
* @public
|
|
37
|
-
*/
|
|
38
|
-
var ConfigIssueRenderer = class {
|
|
39
|
-
constructor() {}
|
|
40
|
-
/**
|
|
41
|
-
* One line per rejected value.
|
|
42
|
-
*
|
|
43
|
-
* @remarks
|
|
44
|
-
* Takes the **error**, not its `issue`, because that is what a `catchTag`
|
|
45
|
-
* hands you and because `issue` is typed `Schema.Defect`, which every call
|
|
46
|
-
* site would otherwise have to reach into. Inside
|
|
47
|
-
* `Effect.catchTag("ConfigValidationError", …)` the error is already this
|
|
48
|
-
* type.
|
|
49
|
-
*
|
|
50
|
-
* An unknown key the schema has a near match for at the same path ends in a
|
|
51
|
-
* hint, `unknown key at theme.colour (did you mean "color"?)`, drawn from the
|
|
52
|
-
* keys the struct declares there (every branch's, under a union) with
|
|
53
|
-
* {@link Fmt.suggest}'s threshold. A key with no near match is drawn exactly
|
|
54
|
-
* as {@link SchemaIssueRenderer} draws it.
|
|
55
|
-
*
|
|
56
|
-
* It cannot throw on a malformed value: the issue tree is validated by
|
|
57
|
-
* a guard before it is read, so a renderer on an error path never becomes the
|
|
58
|
-
* reason a program dies.
|
|
59
|
-
*/
|
|
60
|
-
static render = (error) => formatIssueWithHints(error?.issue);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export { ConfigIssueRenderer };
|