burgee 0.0.0 → 0.2.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.
Files changed (114) hide show
  1. package/README.md +28 -1
  2. package/dist/agent.d.ts +19 -0
  3. package/dist/agent.js +25 -0
  4. package/dist/brand.d.ts +186 -0
  5. package/dist/brand.js +232 -0
  6. package/dist/cli.d.ts +51 -0
  7. package/dist/cli.js +105 -0
  8. package/dist/commander-argument.d.ts +22 -0
  9. package/dist/commander-argument.js +72 -0
  10. package/dist/commander-command.d.ts +345 -0
  11. package/dist/commander-command.js +1605 -0
  12. package/dist/commander-error.d.ts +10 -0
  13. package/dist/commander-error.js +20 -0
  14. package/dist/commander-help.d.ts +67 -0
  15. package/dist/commander-help.js +319 -0
  16. package/dist/commander-option.d.ts +58 -0
  17. package/dist/commander-option.js +164 -0
  18. package/dist/commander-suggest.d.ts +2 -0
  19. package/dist/commander-suggest.js +59 -0
  20. package/dist/commander.d.ts +18 -0
  21. package/dist/commander.js +12 -0
  22. package/dist/completions.d.ts +39 -0
  23. package/dist/completions.js +224 -0
  24. package/dist/config.d.ts +28 -0
  25. package/dist/config.js +98 -0
  26. package/dist/contrast.d.ts +70 -0
  27. package/dist/contrast.js +93 -0
  28. package/dist/execute.d.ts +97 -0
  29. package/dist/execute.js +433 -0
  30. package/dist/exit-code.d.ts +18 -0
  31. package/dist/exit-code.js +12 -0
  32. package/dist/help.d.ts +22 -0
  33. package/dist/help.js +158 -0
  34. package/dist/index.d.ts +16 -1
  35. package/dist/index.js +9 -2
  36. package/dist/manifest.d.ts +192 -0
  37. package/dist/manifest.js +55 -0
  38. package/dist/mcp.d.ts +40 -0
  39. package/dist/mcp.js +111 -0
  40. package/dist/names.d.ts +5 -0
  41. package/dist/names.js +6 -0
  42. package/dist/pkg.d.ts +5 -0
  43. package/dist/pkg.js +21 -0
  44. package/dist/precedence.d.ts +55 -0
  45. package/dist/precedence.js +100 -0
  46. package/dist/runtime.d.ts +27 -0
  47. package/dist/runtime.js +17 -0
  48. package/dist/schema.d.ts +71 -0
  49. package/dist/schema.js +108 -0
  50. package/dist/testing-helpers.d.ts +62 -0
  51. package/dist/testing-helpers.js +110 -0
  52. package/dist/testing.d.ts +10 -0
  53. package/dist/testing.js +3 -0
  54. package/dist/validate.d.ts +27 -0
  55. package/dist/validate.js +133 -0
  56. package/dist/yargs-burgee.d.ts +50 -0
  57. package/dist/yargs-burgee.js +104 -0
  58. package/dist/yargs-cliui.d.ts +56 -0
  59. package/dist/yargs-cliui.js +421 -0
  60. package/dist/yargs-command.d.ts +82 -0
  61. package/dist/yargs-command.js +414 -0
  62. package/dist/yargs-completion.d.ts +41 -0
  63. package/dist/yargs-completion.js +271 -0
  64. package/dist/yargs-factory.d.ts +193 -0
  65. package/dist/yargs-factory.js +1606 -0
  66. package/dist/yargs-helpers.d.ts +6 -0
  67. package/dist/yargs-helpers.js +2 -0
  68. package/dist/yargs-middleware.d.ts +32 -0
  69. package/dist/yargs-middleware.js +81 -0
  70. package/dist/yargs-parser.d.ts +41 -0
  71. package/dist/yargs-parser.js +929 -0
  72. package/dist/yargs-shim.d.ts +54 -0
  73. package/dist/yargs-shim.js +84 -0
  74. package/dist/yargs-usage.d.ts +42 -0
  75. package/dist/yargs-usage.js +479 -0
  76. package/dist/yargs-utils.d.ts +33 -0
  77. package/dist/yargs-utils.js +209 -0
  78. package/dist/yargs-validation.d.ts +26 -0
  79. package/dist/yargs-validation.js +261 -0
  80. package/dist/yargs-y18n.d.ts +21 -0
  81. package/dist/yargs-y18n.js +117 -0
  82. package/dist/yargs.d.ts +6 -0
  83. package/dist/yargs.js +8 -0
  84. package/locales/be.json +46 -0
  85. package/locales/cs.json +51 -0
  86. package/locales/de.json +46 -0
  87. package/locales/en.json +55 -0
  88. package/locales/es.json +46 -0
  89. package/locales/fi.json +49 -0
  90. package/locales/fr.json +53 -0
  91. package/locales/he.json +55 -0
  92. package/locales/hi.json +49 -0
  93. package/locales/hu.json +46 -0
  94. package/locales/id.json +50 -0
  95. package/locales/it.json +46 -0
  96. package/locales/ja.json +51 -0
  97. package/locales/ka.json +55 -0
  98. package/locales/ko.json +49 -0
  99. package/locales/nb.json +44 -0
  100. package/locales/nl.json +49 -0
  101. package/locales/nn.json +44 -0
  102. package/locales/pirate.json +13 -0
  103. package/locales/pl.json +49 -0
  104. package/locales/pt.json +45 -0
  105. package/locales/pt_BR.json +48 -0
  106. package/locales/ru.json +51 -0
  107. package/locales/th.json +46 -0
  108. package/locales/tr.json +48 -0
  109. package/locales/uk_UA.json +51 -0
  110. package/locales/uz.json +52 -0
  111. package/locales/zh_CN.json +48 -0
  112. package/locales/zh_TW.json +51 -0
  113. package/package.json +61 -8
  114. package/dist/index.js.map +0 -1
@@ -0,0 +1,133 @@
1
+ import { kebab } from './names.js';
2
+ export class UsageError extends Error {
3
+ hint;
4
+ constructor(message, hint) {
5
+ super(message);
6
+ this.hint = hint;
7
+ }
8
+ }
9
+ const TYPES = new Set(['string', 'boolean', 'number']);
10
+ export function checkDefinition(name, options) {
11
+ const shorts = new Map();
12
+ const flags = new Map();
13
+ for (const [key, spec] of Object.entries(options)) {
14
+ if (!TYPES.has(spec.type))
15
+ throw new Error(`burgee: option "${key}" of "${name}" has unknown type "${String(spec.type)}"`);
16
+ if (spec.short !== undefined) {
17
+ const owner = shorts.get(spec.short);
18
+ if (owner !== undefined)
19
+ throw new Error(`burgee: options "${owner}" and "${key}" of "${name}" both use -${spec.short}`);
20
+ shorts.set(spec.short, key);
21
+ }
22
+ const flag = kebab(key);
23
+ const clash = flags.get(flag);
24
+ if (clash !== undefined)
25
+ throw new Error(`burgee: options "${clash}" and "${key}" of "${name}" are both --${flag}`);
26
+ flags.set(flag, key);
27
+ if ((spec.minimum !== undefined || spec.maximum !== undefined || spec.integer !== undefined) && spec.type !== 'number') {
28
+ throw new Error(`burgee: option "${key}" of "${name}" declares a numeric bound but is not a number`);
29
+ }
30
+ }
31
+ }
32
+ const isSet = (values, key, sources) => values[key] !== undefined && sources[key]?.source !== 'default';
33
+ const flagList = (keys) => keys.map((k) => `--${kebab(k)}`).join(', ');
34
+ function exactlyOne(keys, on) {
35
+ if (on.length === 1)
36
+ return;
37
+ throw new UsageError(`exactly one of ${flagList(keys)} is required`, on.length === 0 ? 'pass one of them' : `drop all but one of ${flagList(on)}`);
38
+ }
39
+ function atLeastOne(keys, on) {
40
+ if (on.length === 0)
41
+ throw new UsageError(`at least one of ${flagList(keys)} is required`, 'pass one of them');
42
+ }
43
+ function atMostOne(keys, on) {
44
+ if (on.length > 1)
45
+ throw new UsageError(`at most one of ${flagList(keys)} may be given`, `drop all but one of ${flagList(on)}`);
46
+ }
47
+ function noConflict(on) {
48
+ if (on.length > 1)
49
+ throw new UsageError(`${flagList(on)} cannot be used together`, 'drop one of them');
50
+ }
51
+ function implied(a, b, values, sources) {
52
+ if (!isSet(values, a, sources))
53
+ return;
54
+ if (typeof b === 'string') {
55
+ if (!isSet(values, b, sources))
56
+ throw new UsageError(`--${kebab(a)} requires --${kebab(b)}`, `pass --${kebab(b)}`);
57
+ return;
58
+ }
59
+ if (!b(values))
60
+ throw new UsageError(`--${kebab(a)} is not allowed with these values`, `check the values --${kebab(a)} is declared to require`);
61
+ }
62
+ function checkRelation(rel, values, sources) {
63
+ const set = (keys) => keys.filter((k) => isSet(values, k, sources));
64
+ if ('exactlyOneOf' in rel)
65
+ exactlyOne(rel.exactlyOneOf, set(rel.exactlyOneOf));
66
+ else if ('atLeastOneOf' in rel)
67
+ atLeastOne(rel.atLeastOneOf, set(rel.atLeastOneOf));
68
+ else if ('atMostOneOf' in rel)
69
+ atMostOne(rel.atMostOneOf, set(rel.atMostOneOf));
70
+ else if ('conflicts' in rel)
71
+ noConflict(set(rel.conflicts));
72
+ else
73
+ implied(rel.implies[0], rel.implies[1], values, sources);
74
+ }
75
+ export function checkRelations(relations, values, sources) {
76
+ for (const rel of relations ?? [])
77
+ checkRelation(rel, values, sources);
78
+ }
79
+ const isFinite = (n) => Number.isFinite(n);
80
+ const numberOf = (raw) => {
81
+ if (typeof raw === 'number')
82
+ return raw;
83
+ const text = String(raw).trim();
84
+ return text === '' ? Number.NaN : Number(text);
85
+ };
86
+ export function toNumber(key, spec, raw) {
87
+ const n = numberOf(raw);
88
+ const flag = `--${kebab(key)}`;
89
+ if (!isFinite(n))
90
+ throw new UsageError(`${flag} expects a number, got "${String(raw)}"`, `pass ${flag} <number>`);
91
+ if (spec.integer === true && !Number.isInteger(n))
92
+ throw new UsageError(`${flag} expects an integer, got ${n}`, `pass ${flag} ${Math.round(n)}`);
93
+ if (spec.minimum !== undefined && n < spec.minimum)
94
+ throw new UsageError(`${flag} must be at least ${spec.minimum}, got ${n}`, `pass ${flag} ${spec.minimum}`);
95
+ if (spec.maximum !== undefined && n > spec.maximum)
96
+ throw new UsageError(`${flag} must be at most ${spec.maximum}, got ${n}`, `pass ${flag} ${spec.maximum}`);
97
+ return n;
98
+ }
99
+ function checkChoice(key, spec, value) {
100
+ if (spec.choices === undefined || spec.choices.includes(String(value)))
101
+ return;
102
+ throw new UsageError(`--${kebab(key)} must be one of ${spec.choices.join(', ')}, got "${String(value)}"`, `pass --${kebab(key)} ${spec.choices[0] ?? ''}`);
103
+ }
104
+ async function checkSchema(key, spec, value) {
105
+ if (spec.schema === undefined)
106
+ return value;
107
+ const result = await spec.schema['~standard'].validate(value);
108
+ if (result.issues !== undefined) {
109
+ throw new UsageError(`--${kebab(key)}: ${result.issues.map((i) => i.message).join('; ')}`, `check --${kebab(key)}`);
110
+ }
111
+ return result.value;
112
+ }
113
+ export function splitMultiple(spec, raw) {
114
+ const sep = spec.separator ?? ',';
115
+ const parts = Array.isArray(raw) ? raw : [raw];
116
+ return parts.flatMap((p) => (typeof p === 'string' ? p.split(sep).map((s) => s.trim()).filter((s) => s !== '') : [p]));
117
+ }
118
+ async function coerceOne(key, spec, raw) {
119
+ const value = spec.type === 'number' ? toNumber(key, spec, raw) : raw;
120
+ checkChoice(key, spec, value);
121
+ return await checkSchema(key, spec, value);
122
+ }
123
+ async function coerceValue(key, spec, raw) {
124
+ if (spec.multiple !== true)
125
+ return await coerceOne(key, spec, raw);
126
+ return await Promise.all(splitMultiple(spec, raw).map((item) => coerceOne(key, spec, item)));
127
+ }
128
+ export async function coerce(specs, values) {
129
+ const present = Object.entries(specs).filter(([key]) => values[key] !== undefined);
130
+ const coerced = await Promise.all(present.map(async ([key, spec]) => [key, await coerceValue(key, spec, values[key])]));
131
+ return { ...values, ...Object.fromEntries(coerced) };
132
+ }
133
+ export { camel, kebab } from './names.js';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * burgee's additions on yargs syntax — the pure half. `yargs-factory.ts` snapshots what
3
+ * a program registered (options, descriptions, commands and their builders' results) and
4
+ * this module projects that snapshot into the manifest every surface reads (J7, J8).
5
+ * Nothing here runs at parse time unless a burgee surface was asked for.
6
+ */
7
+ import { type Effects, type Manifest, type OptionSpec } from './manifest.js';
8
+ import type { Positional } from './yargs-utils.js';
9
+ /** What one yargs instance (the root, or a command's builder run on a scratch) registered. */
10
+ export interface Snapshot {
11
+ name: string;
12
+ version?: string | undefined;
13
+ description?: string | undefined;
14
+ effects?: Effects | undefined;
15
+ hasHandler: boolean;
16
+ keys: string[];
17
+ aliases: Record<string, string[]>;
18
+ boolean: string[];
19
+ number: string[];
20
+ string: string[];
21
+ count: string[];
22
+ array: string[];
23
+ hiddenOptions: string[];
24
+ demanded: Record<string, string | undefined>;
25
+ deprecated: Record<string, string | boolean | undefined>;
26
+ choices: Record<string, any[]>;
27
+ defaults: Record<string, any>;
28
+ descriptions: Record<string, string | undefined>;
29
+ /** yargs' own `help`, `version` and `show-hidden` keys: burgee serves those itself. */
30
+ skip: readonly string[];
31
+ positionals: {
32
+ demanded: Positional[];
33
+ optional: Positional[];
34
+ };
35
+ commands: {
36
+ name: string;
37
+ description: string | false | undefined;
38
+ deprecated: boolean | string | undefined;
39
+ child: Snapshot;
40
+ }[];
41
+ }
42
+ /** Options as the manifest describes them, on a null-prototype record keyed by the canonical camelCase name. */
43
+ export declare function optionSpecs(s: Snapshot): Record<string, OptionSpec>;
44
+ /**
45
+ * Project a snapshot into the manifest: the root, then every command as a child path.
46
+ * Plugin-contributed nodes survive re-projection, exactly as on the commander façade.
47
+ */
48
+ export declare function projectManifest(manifest: Manifest, root: Snapshot): void;
49
+ /** What a run prints for a handler's return value when the streams are injected. */
50
+ export declare function render(value: unknown): string;
@@ -0,0 +1,104 @@
1
+ import { camelCase } from './yargs-parser.js';
2
+ const DEFER_PREFIX = '__yargsString__:';
3
+ function describe(descriptions, key) {
4
+ const raw = descriptions[key];
5
+ if (raw === undefined || raw === '')
6
+ return undefined;
7
+ return raw.startsWith(DEFER_PREFIX) ? raw.slice(DEFER_PREFIX.length) : raw;
8
+ }
9
+ function typeOf(s, key) {
10
+ const any = (list) => list.includes(key) || (s.aliases[key] ?? []).some((a) => list.includes(a));
11
+ if (any(s.boolean))
12
+ return 'boolean';
13
+ if (any(s.number) || any(s.count))
14
+ return 'number';
15
+ return 'string';
16
+ }
17
+ export function optionSpecs(s) {
18
+ const specs = Object.create(null);
19
+ const aliasOf = new Set();
20
+ for (const [key, list] of Object.entries(s.aliases)) {
21
+ if (s.keys.includes(key))
22
+ for (const a of list)
23
+ aliasOf.add(a);
24
+ }
25
+ const positional = new Set([...s.positionals.demanded, ...s.positionals.optional].flatMap((p) => p.cmd));
26
+ for (const key of s.keys) {
27
+ if (s.skip.includes(key) || aliasOf.has(key) || positional.has(key) || key.includes('.'))
28
+ continue;
29
+ const spec = { type: typeOf(s, key) };
30
+ const aliases = s.aliases[key] ?? [];
31
+ const short = aliases.find((a) => a.length === 1 && !/^[0-9]$/.test(a));
32
+ if (short !== undefined)
33
+ spec.short = short;
34
+ const desc = describe(s.descriptions, key) ?? aliases.map((a) => describe(s.descriptions, a)).find((d) => d !== undefined);
35
+ if (desc !== undefined)
36
+ spec.description = desc;
37
+ if (key in s.demanded || aliases.some((a) => a in s.demanded))
38
+ spec.required = true;
39
+ if (s.array.includes(key) || aliases.some((a) => s.array.includes(a)))
40
+ spec.multiple = true;
41
+ const choices = s.choices[key] ?? aliases.map((a) => s.choices[a]).find((c) => c !== undefined);
42
+ if (choices !== undefined)
43
+ spec.choices = choices.map(String);
44
+ const def = s.defaults[key];
45
+ if (typeof def === 'string' || typeof def === 'boolean' || typeof def === 'number')
46
+ spec.default = def;
47
+ else if (Array.isArray(def) && def.every((d) => typeof d === 'string'))
48
+ spec.default = def;
49
+ if (s.hiddenOptions.includes(key))
50
+ spec.hidden = true;
51
+ const deprecated = s.deprecated[key];
52
+ if (deprecated !== undefined && deprecated !== false)
53
+ spec.deprecated = deprecated;
54
+ Object.defineProperty(specs, camelCase(key), { value: spec, enumerable: true, writable: true, configurable: true });
55
+ }
56
+ return specs;
57
+ }
58
+ function argumentsOf(s) {
59
+ const out = [];
60
+ const push = (p, required) => {
61
+ const name = p.cmd[0];
62
+ const desc = describe(s.descriptions, name);
63
+ out.push({ name, required, variadic: p.variadic, ...(desc === undefined ? {} : { description: desc }) });
64
+ };
65
+ for (const p of s.positionals.demanded)
66
+ push(p, true);
67
+ for (const p of s.positionals.optional)
68
+ push(p, false);
69
+ return out;
70
+ }
71
+ export function projectManifest(manifest, root) {
72
+ const contributed = manifest.commands.filter((c) => c.plugin !== undefined);
73
+ manifest.commands.splice(0, manifest.commands.length, ...contributed);
74
+ manifest.rootPath = [root.name];
75
+ if (root.version !== undefined)
76
+ manifest.version = root.version;
77
+ const visit = (s, at, description, deprecated) => {
78
+ const args = argumentsOf(s);
79
+ manifest.add({
80
+ path: at,
81
+ ...(description === undefined ? {} : { description }),
82
+ ...(s.effects === undefined ? {} : { effects: s.effects }),
83
+ ...(deprecated === undefined || deprecated === false ? {} : { deprecated }),
84
+ options: optionSpecs(s),
85
+ ...(args.length === 0 ? {} : { arguments: args }),
86
+ ...(s.hasHandler ? { run: () => undefined } : {}),
87
+ });
88
+ for (const c of s.commands)
89
+ visit(c.child, [...at, c.name], c.description === false ? undefined : c.description, c.deprecated);
90
+ };
91
+ visit(root, [root.name], root.description, undefined);
92
+ }
93
+ export function render(value) {
94
+ if (value === undefined || value === null)
95
+ return '';
96
+ if (typeof value === 'string')
97
+ return `${value}\n`;
98
+ if (typeof value === 'object' && !Array.isArray(value)) {
99
+ return Object.entries(value)
100
+ .map(([k, v]) => `${k}: ${typeof v === 'string' ? v : JSON.stringify(v)}\n`)
101
+ .join('');
102
+ }
103
+ return `${JSON.stringify(value)}\n`;
104
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * cliui 9 — the column layout yargs' usage renders through — with the string-width,
3
+ * strip-ansi and wrap-ansi it depends on, ported for `burgee/yargs`. The wrapping
4
+ * arithmetic is byte-for-byte the upstream's: yargs' usage tests compare whole help
5
+ * screens.
6
+ */
7
+ export declare function stripAnsi(str: string): string;
8
+ export declare function stringWidth(input: string): number;
9
+ interface WrapOptions {
10
+ hard?: boolean;
11
+ wordWrap?: boolean;
12
+ trim?: boolean;
13
+ }
14
+ export declare function wrapAnsi(string: string, columns: number, options?: WrapOptions): string;
15
+ export interface Column {
16
+ text: string;
17
+ width?: number | undefined;
18
+ align?: 'right' | 'left' | 'center';
19
+ padding: number[];
20
+ border?: boolean;
21
+ }
22
+ interface ColumnArray extends Array<Column> {
23
+ span?: boolean;
24
+ }
25
+ interface Line {
26
+ hidden?: boolean;
27
+ text: string;
28
+ span?: boolean | undefined;
29
+ }
30
+ export declare class UI {
31
+ width: number;
32
+ wrap: boolean;
33
+ rows: ColumnArray[];
34
+ constructor(opts: {
35
+ width: number;
36
+ wrap?: boolean | undefined;
37
+ });
38
+ span(...args: (Column | string)[]): void;
39
+ resetOutput(): void;
40
+ div(...args: (Column | string)[]): ColumnArray;
41
+ private shouldApplyLayoutDSL;
42
+ private applyLayoutDSL;
43
+ private colFromString;
44
+ private measurePadding;
45
+ toString(): string;
46
+ rowToString(row: ColumnArray, lines: Line[]): Line[];
47
+ private renderInline;
48
+ private rasterize;
49
+ private negatePadding;
50
+ private columnWidths;
51
+ }
52
+ export declare function cliui(opts?: {
53
+ width?: number | null | undefined;
54
+ wrap?: boolean | undefined;
55
+ }): UI;
56
+ export {};