goke 6.5.0 → 6.5.1

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 CHANGED
@@ -25,6 +25,14 @@
25
25
  npm install goke
26
26
  ```
27
27
 
28
+ ## Install skill for AI agents
29
+
30
+ ```bash
31
+ npx -y skills add remorses/goke
32
+ ```
33
+
34
+ This installs the repository skill for AI coding agents. In this repo the shipped skill lives at `skills/goke/SKILL.md`.
35
+
28
36
  ## Usage
29
37
 
30
38
  ### Simple Parsing
@@ -390,6 +398,22 @@ cli
390
398
 
391
399
  Prefer injected `fs` for CLI storage instead of importing `node:fs/promises` directly inside actions. That keeps the command portable to JustBash and easier to test.
392
400
 
401
+ ### Path handling
402
+
403
+ Use relative paths with injected `fs` for routine CLI storage paths. When a helper needs to resolve from the current directory, pass injected `process.cwd` into that helper and resolve from there.
404
+
405
+ ```ts
406
+ await fs.mkdir('.mycli', { recursive: true })
407
+ await fs.writeFile('.mycli/auth.json', json, 'utf8')
408
+ console.log('running from', process.cwd)
409
+ ```
410
+
411
+ Why this works:
412
+
413
+ - In normal Node.js runs, relative paths resolve against the host cwd.
414
+ - In JustBash runs, the same relative paths resolve against the sandbox cwd.
415
+ - `process.cwd` mirrors that runtime-specific cwd in both environments.
416
+
393
417
  `goke` also exports the runtime types, so helper functions can use dependency injection without reaching for globals:
394
418
 
395
419
  ```ts
@@ -810,6 +834,78 @@ await bash.exec('parent child commandwithspaces --name Tommy')
810
834
 
811
835
  Prefer the injected `{ fs, console, process }` helpers in command implementations so the same command code works cleanly both in the regular CLI runtime and through the JustBash bridge. The injected `fs` defaults to Node `fs/promises`, and `process.cwd` / `process.env` / `process.stdin` reflect host values in Node but sandbox values inside `createJustBashCommand()`.
812
836
 
837
+ ### Test with real JustBash
838
+
839
+ When a command reads or writes files, test it through real `just-bash` using the existing app CLI. Do not define the CLI inside the test body.
840
+
841
+ ```ts
842
+ import { describe, expect, test } from 'vitest'
843
+ import { Bash, InMemoryFs } from 'just-bash'
844
+ import { cli } from '../src/cli'
845
+
846
+ describe('login command', () => {
847
+ test('writes auth state through the sandbox fs', async () => {
848
+ const virtualFs = new InMemoryFs()
849
+ await virtualFs.mkdir('/project', { recursive: true })
850
+
851
+ const bash = new Bash({
852
+ fs: virtualFs,
853
+ cwd: '/project',
854
+ customCommands: [await cli.createJustBashCommand()],
855
+ })
856
+
857
+ const result = await bash.exec('parent login --token Tommy')
858
+
859
+ expect(result.stdout).toBe('saved credentials\n')
860
+ expect(await virtualFs.readFile('/project/.mycli/auth.json', 'utf8')).toBe(
861
+ '{"token":"Tommy","cwd":"/project"}',
862
+ )
863
+ })
864
+ })
865
+ ```
866
+
867
+ This is the recommended compatibility test whenever a CLI touches storage: run the same CLI once in normal tests and once through real `just-bash`.
868
+
869
+ ### Exposing your CLI as a skill
870
+
871
+ If you build a CLI with goke, keep the skill minimal and point agents to the CLI help output. Put detailed usage in the CLI code and README, not in a duplicated skill file.
872
+
873
+ ````markdown
874
+ <!-- skills/acme/SKILL.md -->
875
+ ---
876
+ name: acme
877
+ description: >
878
+ acme is a deployment CLI. Always run `acme --help` before using it
879
+ to discover available commands, options, and usage examples.
880
+ ---
881
+
882
+ # acme
883
+
884
+ Always run `acme --help` before using this CLI.
885
+ For subcommand details: `acme <command> --help`
886
+ ````
887
+
888
+ ## Contributor Notes
889
+
890
+ ### Rules
891
+
892
+ 1. Use schema-based options for typed values.
893
+ 2. Do not repeat defaults in `.describe(...)` when using `.default()`.
894
+ 3. Do not manually type action callback arguments; let goke infer them.
895
+ 4. Prefer injected `{ fs, console, process }` over global `console`, `process.exit`, or direct `node:fs/promises` imports.
896
+ 5. Use implicit cwd with injected `fs` for CLI storage. When a helper needs current-cwd semantics, pass `process.cwd` from the injected context into that helper.
897
+ 6. Define the CLI in app code and import that same CLI in tests; do not construct a separate CLI inside compatibility tests.
898
+
899
+ ### Version
900
+
901
+ Import `package.json` and use its version field so the CLI stays in sync automatically:
902
+
903
+ ```ts
904
+ import pkg from './package.json' with { type: 'json' }
905
+
906
+ cli.version(pkg.version)
907
+ ```
908
+
813
909
  ## References
814
910
 
815
911
  ### CLI Instance
@@ -867,6 +963,26 @@ Register a middleware function that runs before the matched command action. Midd
867
963
 
868
964
  Print the help message to stdout.
869
965
 
966
+ #### cli.clone(options?)
967
+
968
+ - Type: `(options?: GokeOptions) => Goke`
969
+
970
+ Create a deep copy of the CLI instance with all commands, options, middleware, and event listeners. Override any `GokeOptions` (stdout, stderr, cwd, env, fs, argv, columns, exit) in the clone without affecting the original. Primarily useful in tests to run multiple isolated parses from the same CLI definition:
971
+
972
+ ```ts
973
+ const cli = goke('mycli')
974
+ cli.command('build', 'Build project').action((options, { console }) => {
975
+ console.log('building')
976
+ })
977
+ cli.help()
978
+
979
+ // In tests: override streams without touching the original CLI
980
+ const stdout = { write: vi.fn<(data: string) => void>() }
981
+ const isolated = cli.clone({ stdout })
982
+ isolated.parse(['node', 'mycli', 'build'])
983
+ expect(stdout.write).toHaveBeenCalledWith('building\n')
984
+ ```
985
+
870
986
  #### cli.helpText()
871
987
 
872
988
  - Type: `() => string`
@@ -911,6 +1027,21 @@ Command callbacks receive positional args first, then parsed options, then an in
911
1027
 
912
1028
  - Type: `() => Command`
913
1029
 
1030
+ #### command.hidden()
1031
+
1032
+ - Type: `() => Command`
1033
+
1034
+ Hide a command from the help output listing. The command still matches and runs when invoked directly — only the help display is suppressed. Useful for internal, deprecated, or experimental commands you don't want to advertise.
1035
+
1036
+ ```ts
1037
+ cli
1038
+ .command('internal-reset', 'Reset internal state')
1039
+ .hidden()
1040
+ .action((options, { console }) => {
1041
+ console.log('reset done')
1042
+ })
1043
+ ```
1044
+
914
1045
  #### command.example(example)
915
1046
 
916
1047
  - Type: `(example: CommandExample) => Command`
@@ -919,6 +1050,12 @@ Command callbacks receive positional args first, then parsed options, then an in
919
1050
 
920
1051
  - Type: `(text: string) => Command`
921
1052
 
1053
+ #### command.helpText()
1054
+
1055
+ - Type: `() => string`
1056
+
1057
+ Return the formatted help string for this specific command without printing it. Useful for tests or embedding help text programmatically.
1058
+
922
1059
  ### Events
923
1060
 
924
1061
  Listen to commands:
package/dist/goke.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * - createConsole: factory for console-like objects from output streams
10
10
  * - Utility functions: string helpers, bracket parsing, dot-prop access
11
11
  */
12
- import pc from 'picocolors';
12
+ import pc from './picocolors.js';
13
13
  import mri from "./mri.js";
14
14
  import { GokeError, coerceBySchema, extractJsonSchema, extractSchemaMetadata, isStandardSchema } from "./coerce.js";
15
15
  import { createJustBashCommand as createJustBashCommandBridge } from './just-bash.js';
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Vendored from picocolors by Alexey Raspopov (MIT license).
3
+ * Source: https://github.com/alexeyraspopov/picocolors/blob/main/picocolors.js
4
+ */
5
+ type Formatter = (input: unknown) => string;
6
+ interface PicoColors {
7
+ isColorSupported: boolean;
8
+ reset: Formatter;
9
+ bold: Formatter;
10
+ dim: Formatter;
11
+ italic: Formatter;
12
+ underline: Formatter;
13
+ inverse: Formatter;
14
+ hidden: Formatter;
15
+ strikethrough: Formatter;
16
+ black: Formatter;
17
+ red: Formatter;
18
+ green: Formatter;
19
+ yellow: Formatter;
20
+ blue: Formatter;
21
+ magenta: Formatter;
22
+ cyan: Formatter;
23
+ white: Formatter;
24
+ gray: Formatter;
25
+ bgBlack: Formatter;
26
+ bgRed: Formatter;
27
+ bgGreen: Formatter;
28
+ bgYellow: Formatter;
29
+ bgBlue: Formatter;
30
+ bgMagenta: Formatter;
31
+ bgCyan: Formatter;
32
+ bgWhite: Formatter;
33
+ blackBright: Formatter;
34
+ redBright: Formatter;
35
+ greenBright: Formatter;
36
+ yellowBright: Formatter;
37
+ blueBright: Formatter;
38
+ magentaBright: Formatter;
39
+ cyanBright: Formatter;
40
+ whiteBright: Formatter;
41
+ bgBlackBright: Formatter;
42
+ bgRedBright: Formatter;
43
+ bgGreenBright: Formatter;
44
+ bgYellowBright: Formatter;
45
+ bgBlueBright: Formatter;
46
+ bgMagentaBright: Formatter;
47
+ bgCyanBright: Formatter;
48
+ bgWhiteBright: Formatter;
49
+ }
50
+ declare const createColors: (enabled?: boolean) => PicoColors;
51
+ declare const pc: PicoColors;
52
+ export { createColors };
53
+ export type { PicoColors };
54
+ export default pc;
55
+ //# sourceMappingURL=picocolors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picocolors.d.ts","sourceRoot":"","sources":["../src/picocolors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAA;AAE3C,UAAU,UAAU;IAClB,gBAAgB,EAAE,OAAO,CAAA;IACzB,KAAK,EAAE,SAAS,CAAA;IAChB,IAAI,EAAE,SAAS,CAAA;IACf,GAAG,EAAE,SAAS,CAAA;IACd,MAAM,EAAE,SAAS,CAAA;IACjB,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,SAAS,CAAA;IAClB,MAAM,EAAE,SAAS,CAAA;IACjB,aAAa,EAAE,SAAS,CAAA;IACxB,KAAK,EAAE,SAAS,CAAA;IAChB,GAAG,EAAE,SAAS,CAAA;IACd,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,EAAE,SAAS,CAAA;IACjB,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,SAAS,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,SAAS,CAAA;IAChB,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,SAAS,CAAA;IAClB,KAAK,EAAE,SAAS,CAAA;IAChB,OAAO,EAAE,SAAS,CAAA;IAClB,QAAQ,EAAE,SAAS,CAAA;IACnB,MAAM,EAAE,SAAS,CAAA;IACjB,SAAS,EAAE,SAAS,CAAA;IACpB,MAAM,EAAE,SAAS,CAAA;IACjB,OAAO,EAAE,SAAS,CAAA;IAClB,WAAW,EAAE,SAAS,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;IACpB,WAAW,EAAE,SAAS,CAAA;IACtB,YAAY,EAAE,SAAS,CAAA;IACvB,UAAU,EAAE,SAAS,CAAA;IACrB,aAAa,EAAE,SAAS,CAAA;IACxB,UAAU,EAAE,SAAS,CAAA;IACrB,WAAW,EAAE,SAAS,CAAA;IACtB,aAAa,EAAE,SAAS,CAAA;IACxB,WAAW,EAAE,SAAS,CAAA;IACtB,aAAa,EAAE,SAAS,CAAA;IACxB,cAAc,EAAE,SAAS,CAAA;IACzB,YAAY,EAAE,SAAS,CAAA;IACvB,eAAe,EAAE,SAAS,CAAA;IAC1B,YAAY,EAAE,SAAS,CAAA;IACvB,aAAa,EAAE,SAAS,CAAA;CACzB;AAkCD,QAAA,MAAM,YAAY,GAAI,iBAA0B,KAAG,UA+ClD,CAAA;AAED,QAAA,MAAM,EAAE,YAAiB,CAAA;AAEzB,OAAO,EAAE,YAAY,EAAE,CAAA;AACvB,YAAY,EAAE,UAAU,EAAE,CAAA;AAC1B,eAAe,EAAE,CAAA"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Vendored from picocolors by Alexey Raspopov (MIT license).
3
+ * Source: https://github.com/alexeyraspopov/picocolors/blob/main/picocolors.js
4
+ */
5
+ import { process } from '#runtime';
6
+ const argv = process.argv || [];
7
+ const env = process.env || {};
8
+ const isColorSupported = !(!!env.NO_COLOR || argv.includes('--no-color'))
9
+ && (!!env.FORCE_COLOR
10
+ || argv.includes('--color')
11
+ || process.platform === 'win32'
12
+ || (process.stdout.isTTY && env.TERM !== 'dumb')
13
+ || !!env.CI);
14
+ const replaceClose = (string, close, replace, index) => {
15
+ let result = '';
16
+ let cursor = 0;
17
+ do {
18
+ result += string.substring(cursor, index) + replace;
19
+ cursor = index + close.length;
20
+ index = string.indexOf(close, cursor);
21
+ } while (~index);
22
+ return result + string.substring(cursor);
23
+ };
24
+ const formatter = (open, close, replace = open) => (input) => {
25
+ const string = String(input);
26
+ const index = string.indexOf(close, open.length);
27
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
28
+ };
29
+ const createColors = (enabled = isColorSupported) => {
30
+ const f = enabled ? formatter : () => String;
31
+ return {
32
+ isColorSupported: enabled,
33
+ reset: f('\x1b[0m', '\x1b[0m'),
34
+ bold: f('\x1b[1m', '\x1b[22m', '\x1b[22m\x1b[1m'),
35
+ dim: f('\x1b[2m', '\x1b[22m', '\x1b[22m\x1b[2m'),
36
+ italic: f('\x1b[3m', '\x1b[23m'),
37
+ underline: f('\x1b[4m', '\x1b[24m'),
38
+ inverse: f('\x1b[7m', '\x1b[27m'),
39
+ hidden: f('\x1b[8m', '\x1b[28m'),
40
+ strikethrough: f('\x1b[9m', '\x1b[29m'),
41
+ black: f('\x1b[30m', '\x1b[39m'),
42
+ red: f('\x1b[31m', '\x1b[39m'),
43
+ green: f('\x1b[32m', '\x1b[39m'),
44
+ yellow: f('\x1b[33m', '\x1b[39m'),
45
+ blue: f('\x1b[34m', '\x1b[39m'),
46
+ magenta: f('\x1b[35m', '\x1b[39m'),
47
+ cyan: f('\x1b[36m', '\x1b[39m'),
48
+ white: f('\x1b[37m', '\x1b[39m'),
49
+ gray: f('\x1b[90m', '\x1b[39m'),
50
+ bgBlack: f('\x1b[40m', '\x1b[49m'),
51
+ bgRed: f('\x1b[41m', '\x1b[49m'),
52
+ bgGreen: f('\x1b[42m', '\x1b[49m'),
53
+ bgYellow: f('\x1b[43m', '\x1b[49m'),
54
+ bgBlue: f('\x1b[44m', '\x1b[49m'),
55
+ bgMagenta: f('\x1b[45m', '\x1b[49m'),
56
+ bgCyan: f('\x1b[46m', '\x1b[49m'),
57
+ bgWhite: f('\x1b[47m', '\x1b[49m'),
58
+ blackBright: f('\x1b[90m', '\x1b[39m'),
59
+ redBright: f('\x1b[91m', '\x1b[39m'),
60
+ greenBright: f('\x1b[92m', '\x1b[39m'),
61
+ yellowBright: f('\x1b[93m', '\x1b[39m'),
62
+ blueBright: f('\x1b[94m', '\x1b[39m'),
63
+ magentaBright: f('\x1b[95m', '\x1b[39m'),
64
+ cyanBright: f('\x1b[96m', '\x1b[39m'),
65
+ whiteBright: f('\x1b[97m', '\x1b[39m'),
66
+ bgBlackBright: f('\x1b[100m', '\x1b[49m'),
67
+ bgRedBright: f('\x1b[101m', '\x1b[49m'),
68
+ bgGreenBright: f('\x1b[102m', '\x1b[49m'),
69
+ bgYellowBright: f('\x1b[103m', '\x1b[49m'),
70
+ bgBlueBright: f('\x1b[104m', '\x1b[49m'),
71
+ bgMagentaBright: f('\x1b[105m', '\x1b[49m'),
72
+ bgCyanBright: f('\x1b[106m', '\x1b[49m'),
73
+ bgWhiteBright: f('\x1b[107m', '\x1b[49m'),
74
+ };
75
+ };
76
+ const pc = createColors();
77
+ export { createColors };
78
+ export default pc;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goke",
3
- "version": "6.5.0",
3
+ "version": "6.5.1",
4
4
  "type": "module",
5
5
  "description": "Simple yet powerful framework for building command-line apps. Inspired by cac.",
6
6
  "repository": {
@@ -48,9 +48,7 @@
48
48
  "dist",
49
49
  "src"
50
50
  ],
51
- "dependencies": {
52
- "picocolors": "^1.1.1"
53
- },
51
+ "dependencies": {},
54
52
  "author": "remorses, egoist <0x142857@gmail.com>",
55
53
  "license": "MIT",
56
54
  "devDependencies": {
package/src/goke.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  * - Utility functions: string helpers, bracket parsing, dot-prop access
11
11
  */
12
12
 
13
- import pc from 'picocolors'
13
+ import pc from './picocolors.js'
14
14
  import mri from "./mri.js"
15
15
  import { GokeError, coerceBySchema, extractJsonSchema, extractSchemaMetadata, isStandardSchema } from "./coerce.js"
16
16
  import type { StandardJSONSchemaV1 } from "./coerce.js"
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Vendored from picocolors by Alexey Raspopov (MIT license).
3
+ * Source: https://github.com/alexeyraspopov/picocolors/blob/main/picocolors.js
4
+ */
5
+
6
+ import { process } from '#runtime'
7
+
8
+ type Formatter = (input: unknown) => string
9
+
10
+ interface PicoColors {
11
+ isColorSupported: boolean
12
+ reset: Formatter
13
+ bold: Formatter
14
+ dim: Formatter
15
+ italic: Formatter
16
+ underline: Formatter
17
+ inverse: Formatter
18
+ hidden: Formatter
19
+ strikethrough: Formatter
20
+ black: Formatter
21
+ red: Formatter
22
+ green: Formatter
23
+ yellow: Formatter
24
+ blue: Formatter
25
+ magenta: Formatter
26
+ cyan: Formatter
27
+ white: Formatter
28
+ gray: Formatter
29
+ bgBlack: Formatter
30
+ bgRed: Formatter
31
+ bgGreen: Formatter
32
+ bgYellow: Formatter
33
+ bgBlue: Formatter
34
+ bgMagenta: Formatter
35
+ bgCyan: Formatter
36
+ bgWhite: Formatter
37
+ blackBright: Formatter
38
+ redBright: Formatter
39
+ greenBright: Formatter
40
+ yellowBright: Formatter
41
+ blueBright: Formatter
42
+ magentaBright: Formatter
43
+ cyanBright: Formatter
44
+ whiteBright: Formatter
45
+ bgBlackBright: Formatter
46
+ bgRedBright: Formatter
47
+ bgGreenBright: Formatter
48
+ bgYellowBright: Formatter
49
+ bgBlueBright: Formatter
50
+ bgMagentaBright: Formatter
51
+ bgCyanBright: Formatter
52
+ bgWhiteBright: Formatter
53
+ }
54
+
55
+ const argv = process.argv || []
56
+ const env = process.env || {}
57
+ const isColorSupported =
58
+ !(!!env.NO_COLOR || argv.includes('--no-color'))
59
+ && (
60
+ !!env.FORCE_COLOR
61
+ || argv.includes('--color')
62
+ || process.platform === 'win32'
63
+ || (process.stdout.isTTY && env.TERM !== 'dumb')
64
+ || !!env.CI
65
+ )
66
+
67
+ const replaceClose = (string: string, close: string, replace: string, index: number) => {
68
+ let result = ''
69
+ let cursor = 0
70
+
71
+ do {
72
+ result += string.substring(cursor, index) + replace
73
+ cursor = index + close.length
74
+ index = string.indexOf(close, cursor)
75
+ } while (~index)
76
+
77
+ return result + string.substring(cursor)
78
+ }
79
+
80
+ const formatter = (open: string, close: string, replace = open): Formatter =>
81
+ (input) => {
82
+ const string = String(input)
83
+ const index = string.indexOf(close, open.length)
84
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close
85
+ }
86
+
87
+ const createColors = (enabled = isColorSupported): PicoColors => {
88
+ const f = enabled ? formatter : () => String
89
+
90
+ return {
91
+ isColorSupported: enabled,
92
+ reset: f('\x1b[0m', '\x1b[0m'),
93
+ bold: f('\x1b[1m', '\x1b[22m', '\x1b[22m\x1b[1m'),
94
+ dim: f('\x1b[2m', '\x1b[22m', '\x1b[22m\x1b[2m'),
95
+ italic: f('\x1b[3m', '\x1b[23m'),
96
+ underline: f('\x1b[4m', '\x1b[24m'),
97
+ inverse: f('\x1b[7m', '\x1b[27m'),
98
+ hidden: f('\x1b[8m', '\x1b[28m'),
99
+ strikethrough: f('\x1b[9m', '\x1b[29m'),
100
+ black: f('\x1b[30m', '\x1b[39m'),
101
+ red: f('\x1b[31m', '\x1b[39m'),
102
+ green: f('\x1b[32m', '\x1b[39m'),
103
+ yellow: f('\x1b[33m', '\x1b[39m'),
104
+ blue: f('\x1b[34m', '\x1b[39m'),
105
+ magenta: f('\x1b[35m', '\x1b[39m'),
106
+ cyan: f('\x1b[36m', '\x1b[39m'),
107
+ white: f('\x1b[37m', '\x1b[39m'),
108
+ gray: f('\x1b[90m', '\x1b[39m'),
109
+ bgBlack: f('\x1b[40m', '\x1b[49m'),
110
+ bgRed: f('\x1b[41m', '\x1b[49m'),
111
+ bgGreen: f('\x1b[42m', '\x1b[49m'),
112
+ bgYellow: f('\x1b[43m', '\x1b[49m'),
113
+ bgBlue: f('\x1b[44m', '\x1b[49m'),
114
+ bgMagenta: f('\x1b[45m', '\x1b[49m'),
115
+ bgCyan: f('\x1b[46m', '\x1b[49m'),
116
+ bgWhite: f('\x1b[47m', '\x1b[49m'),
117
+ blackBright: f('\x1b[90m', '\x1b[39m'),
118
+ redBright: f('\x1b[91m', '\x1b[39m'),
119
+ greenBright: f('\x1b[92m', '\x1b[39m'),
120
+ yellowBright: f('\x1b[93m', '\x1b[39m'),
121
+ blueBright: f('\x1b[94m', '\x1b[39m'),
122
+ magentaBright: f('\x1b[95m', '\x1b[39m'),
123
+ cyanBright: f('\x1b[96m', '\x1b[39m'),
124
+ whiteBright: f('\x1b[97m', '\x1b[39m'),
125
+ bgBlackBright: f('\x1b[100m', '\x1b[49m'),
126
+ bgRedBright: f('\x1b[101m', '\x1b[49m'),
127
+ bgGreenBright: f('\x1b[102m', '\x1b[49m'),
128
+ bgYellowBright: f('\x1b[103m', '\x1b[49m'),
129
+ bgBlueBright: f('\x1b[104m', '\x1b[49m'),
130
+ bgMagentaBright: f('\x1b[105m', '\x1b[49m'),
131
+ bgCyanBright: f('\x1b[106m', '\x1b[49m'),
132
+ bgWhiteBright: f('\x1b[107m', '\x1b[49m'),
133
+ }
134
+ }
135
+
136
+ const pc = createColors()
137
+
138
+ export { createColors }
139
+ export type { PicoColors }
140
+ export default pc