burgee 0.7.1 → 0.9.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 (65) hide show
  1. package/README.md +1 -0
  2. package/dist/check.d.ts +22 -0
  3. package/dist/check.js +35 -0
  4. package/dist/cli.d.ts +31 -3
  5. package/dist/cli.js +36 -7
  6. package/dist/commander/argument.js +0 -3
  7. package/dist/commander/command.d.ts +7 -3
  8. package/dist/commander/command.js +54 -187
  9. package/dist/commander/error.js +0 -2
  10. package/dist/commander/help.js +0 -17
  11. package/dist/commander/option.js +0 -14
  12. package/dist/compat.d.ts +30 -0
  13. package/dist/compat.js +4 -0
  14. package/dist/config.d.ts +10 -0
  15. package/dist/config.js +2 -0
  16. package/dist/definition.d.ts +24 -6
  17. package/dist/definition.js +18 -14
  18. package/dist/execute.d.ts +1 -0
  19. package/dist/execute.js +45 -27
  20. package/dist/exit-code.d.ts +17 -1
  21. package/dist/exit-code.js +1 -0
  22. package/dist/help-entry.d.ts +2 -0
  23. package/dist/help-entry.js +1 -0
  24. package/dist/help.d.ts +12 -0
  25. package/dist/help.js +6 -0
  26. package/dist/index.d.ts +32 -7
  27. package/dist/index.js +1 -7
  28. package/dist/mcp-entry.d.ts +2 -0
  29. package/dist/mcp-entry.js +1 -0
  30. package/dist/mcp.d.ts +33 -13
  31. package/dist/mcp.js +4 -3
  32. package/dist/meow/parse.d.ts +21 -0
  33. package/dist/meow/parse.js +43 -0
  34. package/dist/meow/present.d.ts +35 -0
  35. package/dist/meow/present.js +58 -0
  36. package/dist/meow/types.d.ts +47 -0
  37. package/dist/meow/types.js +3 -0
  38. package/dist/meow/validate.d.ts +35 -0
  39. package/dist/meow/validate.js +144 -0
  40. package/dist/meow.d.ts +6 -0
  41. package/dist/meow.js +146 -0
  42. package/dist/migrate.d.ts +142 -0
  43. package/dist/migrate.js +284 -0
  44. package/dist/plugin.d.ts +1 -1
  45. package/dist/plugin.js +1 -1
  46. package/dist/runtime.d.ts +2 -0
  47. package/dist/runtime.js +3 -0
  48. package/dist/schema-entry.d.ts +3 -0
  49. package/dist/schema-entry.js +2 -0
  50. package/dist/schema.json +1 -1
  51. package/dist/testing-helpers.js +3 -1
  52. package/dist/validate.d.ts +15 -0
  53. package/dist/validate.js +10 -0
  54. package/dist/yargs/burgee.js +0 -14
  55. package/dist/yargs/cliui.js +0 -53
  56. package/dist/yargs/command.js +0 -7
  57. package/dist/yargs/completion.js +0 -5
  58. package/dist/yargs/factory.js +7 -57
  59. package/dist/yargs/middleware.js +0 -5
  60. package/dist/yargs/shim.js +0 -20
  61. package/dist/yargs/usage.js +0 -8
  62. package/dist/yargs/utils.js +0 -11
  63. package/dist/yargs/validation.js +0 -6
  64. package/dist/yargs/y18n.js +0 -6
  65. package/package.json +32 -7
package/dist/schema.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://github.com/ofri-peretz/burgee/blob/main/packages/flagstaff/src/schema.json","title":"flagstaff plugin","description":"A plugin is one plain object. Everything in it is data that can be read without running it; the only functions allowed are a component's `static` (required) and `frame` (optional). A spinner or component without a static projection is refused at register().","type":"object","required":["name"],"additionalProperties":true,"properties":{"name":{"type":"string","minLength":1,"description":"The plugin's name; also the prefix a host may use when two plugins contribute the same key."},"contract":{"type":"integer","minimum":1,"description":"The plugin contract this object follows. A host refuses a newer contract than it knows."},"tokens":{"type":"object","description":"A roundel theme: semantic token name to a hex colour, contrast-checked when flown.","additionalProperties":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"propertyNames":{"enum":["error","warn","ok","hint","muted","command","flag","value","heading","ground"],"description":"roundel's ten semantic tokens, and nothing else — `roundel`'s own validate() refuses any other name."}},"glyphs":{"type":"object","description":"Symbols by meaning: `ok`, `fail`, `warn`, `info`, `running`. A plugin that ships glyphs changes every built-in that draws one.","additionalProperties":{"type":"string","minLength":1}},"spinners":{"type":"object","description":"Spinner styles by name, in cli-spinners' shape plus the static projection.","additionalProperties":{"$ref":"#/$defs/spinner"}},"borders":{"type":"object","description":"Border styles a box can be drawn with, by name.","additionalProperties":{"$ref":"#/$defs/border"}},"components":{"type":"object","description":"Components by name: `static(state)` returns the text a pipe, an agent or a screen reader gets; `frame(t, state)` is the optional animated form.","additionalProperties":{"$ref":"#/$defs/component"}},"capabilities":{"$ref":"#/$defs/capabilities"}},"$defs":{"spinner":{"type":"object","required":["frames","interval","static"],"properties":{"frames":{"type":"array","items":{"type":"string"},"minItems":1},"interval":{"type":"integer","minimum":1,"description":"Milliseconds between frames on a terminal."},"static":{"type":"string","description":"What a pipe prints instead of the animation."}}},"component":{"type":"object","required":["static"],"properties":{"static":{"description":"(state) => string. Required: the projection every non-terminal mode prints."},"frame":{"description":"(t, state) => string. Optional: the frame at t milliseconds since hoisting."},"sample":{"type":"object","required":["running","done"],"description":"Two states to *show* this component with: `flagstaff check` and the docs gallery render `running` then `done`. Omitted, they assume `{ phase: 'running' }` and `{ phase: 'done' }` and say so in the output. The loop never reads it — a running program's state comes from the program.","properties":{"running":{"description":"The state to open with."},"done":{"description":"The state to close with."}}},"interval":{"type":"integer","minimum":1,"description":"Milliseconds between repaints when `frame` is given; 80 when omitted."}}},"border":{"type":"object","required":["topLeft","top","topRight","left","right","bottomLeft","bottom","bottomRight"],"description":"cli-boxes' shape exactly, so that corpus imports unchanged.","properties":{"topLeft":{"type":"string"},"top":{"type":"string"},"topRight":{"type":"string"},"left":{"type":"string"},"right":{"type":"string"},"bottomLeft":{"type":"string"},"bottom":{"type":"string"},"bottomRight":{"type":"string"}}},"capability":{"type":"object","required":["name","osc","when","encode","fallback"],"additionalProperties":false,"description":"One paratext capability: what it says to the terminal, when the terminal is believed to understand it, and what prints when it does not. No functions, so it travels through JSON. `encode` and `fallback` are templates: `{field}` is the field's value, `{field|base64}` is it base64-encoded, and `[ … ]` is emitted only when every field inside it has a value.","properties":{"name":{"type":"string","minLength":1,"description":"How callers name it. Registering an existing name replaces it — how a caller corrects a guess we got wrong."},"osc":{"description":"The OSC code this speaks, or 'BEL' for the bell and for protocols that are not OSC at all, such as Kitty's.","oneOf":[{"type":"integer","minimum":0},{"const":"BEL"}]},"when":{"type":"object","description":"When the terminal is believed to understand it. Every clause must hold; `termProgram` and `envAny` are ORs within themselves. Guesses — no terminal answers 'do you do OSC 1337' — and therefore data a caller can replace.","additionalProperties":false,"properties":{"tty":{"type":"boolean","description":"Refuse a pipe. Almost always true: a file that receives OSC gets control bytes in it."},"termProgram":{"type":"array","items":{"type":"string"},"description":"Any one of these TERM_PROGRAM values."},"envAny":{"type":"array","items":{"type":"string"},"description":"Any one of these environment variables merely being set, as VTE announces itself."},"term":{"type":"string","description":"An exact TERM — Kitty is xterm-kitty."}}},"encode":{"type":"string","minLength":1,"description":"The bytes, as a template, for a terminal that does understand."},"fallback":{"type":"string","description":"What to print when it does not — PRINCIPLES rule 6. '' is a legitimate answer, a window title having nothing to say in a log; absence is not, which is why this is required and may be ''."}},"examples":[{"name":"kitty-image","osc":"BEL","when":{"tty":true,"term":"xterm-kitty"},"encode":"\u001b_Ga=T,f=100;{base64}\u001b\\","fallback":"{caption}"}]},"capabilities":{"type":"object","description":"paratext capabilities by name — the OSC section of a plugin, read the way flagstaff reads `spinners`.","additionalProperties":{"$ref":"#/$defs/capability"}},"capabilityDocument":{"description":"What paratext's `check()` accepts. Two shapes, and only one of them survives 1.0.","oneOf":[{"description":"The family shape: a plugin carrying its capabilities under `capabilities`.","type":"object","required":["name","capabilities"],"properties":{"name":{"type":"string","minLength":1},"contract":{"type":"integer","minimum":1},"capabilities":{"$ref":"#/$defs/capabilities"}}},{"deprecated":true,"description":"Deprecated: one capability as the whole document, the shape paratext's schema had before this one absorbed it. Accepted for one minor release, removed at 1.0 — `check()` validates it and says so.","$ref":"#/$defs/capability"}]}}}
1
+ {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://github.com/ofri-peretz/burgee/blob/main/packages/flagstaff/src/schema.json","title":"flagstaff plugin","description":"A plugin is one plain object. Everything in it is data that can be read without running it; the only functions allowed are a component's `static` (required) and `frame` (optional). A spinner or component without a static projection is refused at register().","type":"object","required":["name"],"additionalProperties":true,"properties":{"name":{"type":"string","minLength":1,"description":"The plugin's name; also the prefix a host may use when two plugins contribute the same key."},"contract":{"type":"integer","minimum":1,"description":"The plugin contract this object follows. A host refuses a newer contract than it knows."},"tokens":{"type":"object","description":"A roundel theme: semantic token name to a hex colour, contrast-checked when flown.","additionalProperties":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"propertyNames":{"enum":["error","warn","ok","hint","muted","command","flag","value","heading","ground"],"description":"roundel's ten semantic tokens, and nothing else — `roundel`'s own validate() refuses any other name."}},"glyphs":{"type":"object","description":"Symbols by meaning: `ok`, `fail`, `warn`, `info`, `running`. A plugin that ships glyphs changes every built-in that draws one.","additionalProperties":{"type":"string","minLength":1}},"spinners":{"type":"object","description":"Spinner styles by name, in cli-spinners' shape plus the static projection.","additionalProperties":{"$ref":"#/$defs/spinner"}},"borders":{"type":"object","description":"Border styles a box can be drawn with, by name.","additionalProperties":{"$ref":"#/$defs/border"}},"components":{"type":"object","description":"Components by name: `static(state)` returns the text a pipe, an agent or a screen reader gets; `frame(t, state)` is the optional animated form.","additionalProperties":{"$ref":"#/$defs/component"}},"capabilities":{"$ref":"#/$defs/capabilities"},"widths":{"$ref":"#/$defs/widths"}},"$defs":{"spinner":{"type":"object","required":["frames","interval","static"],"properties":{"frames":{"type":"array","items":{"type":"string"},"minItems":1},"interval":{"type":"integer","minimum":1,"description":"Milliseconds between frames on a terminal."},"static":{"type":"string","description":"What a pipe prints instead of the animation."}}},"component":{"type":"object","required":["static"],"properties":{"static":{"description":"(state) => string. Required: the projection every non-terminal mode prints."},"frame":{"description":"(t, state) => string. Optional: the frame at t milliseconds since hoisting."},"sample":{"type":"object","required":["running","done"],"description":"Two states to *show* this component with: `flagstaff check` and the docs gallery render `running` then `done`. Omitted, they assume `{ phase: 'running' }` and `{ phase: 'done' }` and say so in the output. The loop never reads it — a running program's state comes from the program.","properties":{"running":{"description":"The state to open with."},"done":{"description":"The state to close with."}}},"interval":{"type":"integer","minimum":1,"description":"Milliseconds between repaints when `frame` is given; 80 when omitted."}}},"border":{"type":"object","required":["topLeft","top","topRight","left","right","bottomLeft","bottom","bottomRight"],"description":"cli-boxes' shape exactly, so that corpus imports unchanged.","properties":{"topLeft":{"type":"string"},"top":{"type":"string"},"topRight":{"type":"string"},"left":{"type":"string"},"right":{"type":"string"},"bottomLeft":{"type":"string"},"bottom":{"type":"string"},"bottomRight":{"type":"string"}}},"capability":{"type":"object","required":["name","osc","when","encode","fallback"],"additionalProperties":false,"description":"One paratext capability: what it says to the terminal, when the terminal is believed to understand it, and what prints when it does not. No functions, so it travels through JSON. `encode` and `fallback` are templates: `{field}` is the field's value, `{field|base64}` is it base64-encoded, and `[ … ]` is emitted only when every field inside it has a value.","properties":{"name":{"type":"string","minLength":1,"description":"How callers name it. Registering an existing name replaces it — how a caller corrects a guess we got wrong."},"osc":{"description":"The OSC code this speaks, or 'BEL' for the bell and for protocols that are not OSC at all, such as Kitty's.","oneOf":[{"type":"integer","minimum":0},{"const":"BEL"}]},"when":{"type":"object","description":"When the terminal is believed to understand it. Every clause must hold; `termProgram` and `envAny` are ORs within themselves. Guesses — no terminal answers 'do you do OSC 1337' — and therefore data a caller can replace.","additionalProperties":false,"properties":{"tty":{"type":"boolean","description":"Refuse a pipe. Almost always true: a file that receives OSC gets control bytes in it."},"termProgram":{"type":"array","items":{"type":"string"},"description":"Any one of these TERM_PROGRAM values."},"envAny":{"type":"array","items":{"type":"string"},"description":"Any one of these environment variables merely being set, as VTE announces itself."},"term":{"type":"string","description":"An exact TERM — Kitty is xterm-kitty."}}},"encode":{"type":"string","minLength":1,"description":"The bytes, as a template, for a terminal that does understand."},"fallback":{"type":"string","description":"What to print when it does not — PRINCIPLES rule 6. '' is a legitimate answer, a window title having nothing to say in a log; absence is not, which is why this is required and may be ''."}},"examples":[{"name":"kitty-image","osc":"BEL","when":{"tty":true,"term":"xterm-kitty"},"encode":"\u001b_Ga=T,f=100;{base64}\u001b\\","fallback":"{caption}"}]},"capabilities":{"type":"object","description":"paratext capabilities by name — the OSC section of a plugin, read the way flagstaff reads `spinners`.","additionalProperties":{"$ref":"#/$defs/capability"}},"capabilityDocument":{"description":"What paratext's `check()` accepts. Two shapes, and only one of them survives 1.0.","oneOf":[{"description":"The family shape: a plugin carrying its capabilities under `capabilities`.","type":"object","required":["name","capabilities"],"properties":{"name":{"type":"string","minLength":1},"contract":{"type":"integer","minimum":1},"capabilities":{"$ref":"#/$defs/capabilities"}}},{"deprecated":true,"description":"Deprecated: one capability as the whole document, the shape paratext's schema had before this one absorbed it. Accepted for one minor release, removed at 1.0 — `check()` validates it and says so.","$ref":"#/$defs/capability"}]},"widthRange":{"type":"array","description":"One inclusive code-point range, as [low, high]. A single code point is written [n, n].","items":{"type":"integer","minimum":0,"maximum":1114111},"minItems":2,"maxItems":2},"widthOverride":{"type":"object","description":"A linegauge width override: the column count a named set of code-point ranges occupies, for a terminal that disagrees with the Unicode tables. Data only — no function, so it can be written in a config file, diffed, and printed by `linegauge check` without running anyone code.","required":["ranges","columns","why"],"additionalProperties":false,"properties":{"ranges":{"type":"array","description":"The code points this override applies to.","items":{"$ref":"#/$defs/widthRange"},"minItems":1},"columns":{"type":"integer","description":"Columns each cluster in those ranges occupies: 0 for a zero-width mark, 1 narrow, 2 wide.","minimum":0,"maximum":2},"why":{"type":"string","description":"The terminal or the reason. Required, because a width table with no provenance is one nobody can audit when it turns out to be wrong — which is the normal outcome for ambiguous width.","minLength":1}}},"widths":{"type":"object","description":"linegauge width overrides by name — the measurement section of a plugin, read the way flagstaff reads `spinners`.","additionalProperties":{"$ref":"#/$defs/widthOverride"}}}}
@@ -133,7 +133,9 @@ export async function runBurgee(program, opts) {
133
133
  await execute(program, {
134
134
  argv: rt.argv,
135
135
  env: rt.env,
136
- stdout: rt.stdout,
136
+ cwd: rt.cwd,
137
+ stdin: rt.stdin,
138
+ stdout: { write: rt.stdout.write, isTTY: rt.isTTY.stdout },
137
139
  stderr: rt.stderr,
138
140
  exit: (c) => rt.exit(c),
139
141
  root: program.rootPath,
@@ -11,6 +11,21 @@ export declare class UsageError extends Error {
11
11
  readonly hint?: string | undefined;
12
12
  constructor(message: string, hint?: string | undefined);
13
13
  }
14
+ /**
15
+ * E6 — the far side said no. Throw this and the run leaves with `ExitCode.AUTH`.
16
+ *
17
+ * The one error class whose *response* is unambiguous: not "read the message and decide" but
18
+ * "get a credential and run it again". A handler that throws a bare `Error` for a 401 gets
19
+ * `RUNTIME`, which is the code for everything, and a caller retrying on it retries forever.
20
+ *
21
+ * `fix` is the exact command that gets the credential, where the program knows it — `hint` is
22
+ * prose a person reads and `fix` is a line a caller runs, which is the turn the field saves.
23
+ */
24
+ export declare class AuthError extends Error {
25
+ readonly hint?: string | undefined;
26
+ readonly fix?: string | undefined;
27
+ constructor(message: string, hint?: string | undefined, fix?: string | undefined);
28
+ }
14
29
  type Sources = Record<string, {
15
30
  source: string;
16
31
  }>;
package/dist/validate.js CHANGED
@@ -6,6 +6,16 @@ export class UsageError extends Error {
6
6
  this.hint = hint;
7
7
  }
8
8
  }
9
+ export class AuthError extends Error {
10
+ hint;
11
+ fix;
12
+ constructor(message, hint, fix) {
13
+ super(message);
14
+ this.hint = hint;
15
+ this.fix = fix;
16
+ this.name = 'AuthError';
17
+ }
18
+ }
9
19
  const isSet = (values, key, sources) => values[key] !== undefined && sources[key]?.source !== 'default';
10
20
  const flagList = (keys) => flagsOf(keys).join(', ');
11
21
  function exactlyOne(keys, on) {
@@ -1,10 +1,3 @@
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 {} from '../manifest.js';
8
1
  import { camelCase } from '../yargs-parser.js';
9
2
  const DEFER_PREFIX = '__yargsString__:';
10
3
  function describe(descriptions, key) {
@@ -21,7 +14,6 @@ function typeOf(s, key) {
21
14
  return 'number';
22
15
  return 'string';
23
16
  }
24
- /** Options as the manifest describes them, on a null-prototype record keyed by the canonical camelCase name. */
25
17
  export function optionSpecs(s) {
26
18
  const specs = Object.create(null);
27
19
  const aliasOf = new Set();
@@ -76,10 +68,6 @@ function argumentsOf(s) {
76
68
  push(p, false);
77
69
  return out;
78
70
  }
79
- /**
80
- * Project a snapshot into the manifest: the root, then every command as a child path.
81
- * Plugin-contributed nodes survive re-projection, exactly as on the commander façade.
82
- */
83
71
  export function projectManifest(manifest, root) {
84
72
  const contributed = manifest.commands.filter((c) => c.plugin !== undefined);
85
73
  manifest.commands.splice(0, manifest.commands.length, ...contributed);
@@ -102,7 +90,6 @@ export function projectManifest(manifest, root) {
102
90
  };
103
91
  visit(root, [root.name], root.description, undefined);
104
92
  }
105
- /** What a run prints for a handler's return value when the streams are injected. */
106
93
  export function render(value) {
107
94
  if (value === undefined || value === null)
108
95
  return '';
@@ -115,4 +102,3 @@ export function render(value) {
115
102
  }
116
103
  return `${JSON.stringify(value)}\n`;
117
104
  }
118
- //# sourceMappingURL=burgee.js.map
@@ -1,35 +1,7 @@
1
1
  import { strip, width, wrap } from "linegauge";
2
2
  import { host } from "../runtime.js";
3
- /**
4
- * cliui 9 — the column layout yargs' usage renders through — with the wrap-ansi it depends
5
- * on, ported for `burgee/yargs`. Width and escape-stripping come from linegauge. The wrapping
6
- * arithmetic is byte-for-byte the upstream's: yargs' usage tests compare whole help
7
- * screens.
8
- */
9
- /*
10
- * `width` and `strip` are linegauge's — measuring text and removing escapes is the layer
11
- * below this one, and this file had its own copies of both. They were not merely duplicated,
12
- * they were wrong: the ITU T.416 sub-parameter form `ESC[38:2::255:0:0m`, which chalk emits
13
- * for truecolor, left `:2::255:0:0m` behind and measured a 13-column string as 25. linegauge
14
- * fixed that in its own `strip`; burgee inherited nothing because it was not asking.
15
- *
16
- * The names stay, because `usage.ts` and `shim.ts` import them and the upstream port reads
17
- * the way cliui reads.
18
- */
19
3
  export const stripAnsi = (str) => typeof str === "string" ? strip(str) : str;
20
4
  export const stringWidth = (input) => typeof input === "string" ? width(input) : 0;
21
- /*
22
- * The wrap is linegauge's too. This file carried a wrap-ansi port — ansi-styles' open→close
23
- * map, an escape-state machine over every character, hyperlink re-opening — to wrap a line
24
- * without breaking the styling across it. That is the same job `linegauge/wrap` exists for
25
- * and grades against wrap-ansi, so burgee kept a second implementation of a thing the layer
26
- * below already owned.
27
- *
28
- * Checked before swapping, because yargs' usage tests compare whole help screens: the two
29
- * agreed on all ten shapes probed — plain prose at several widths, an unbreakable word,
30
- * SGR-coloured text, single characters, CJK, an embedded newline, leading and trailing
31
- * spaces, empty, and a string exactly the column width.
32
- */
33
5
  export function wrapAnsi(string, columns, options) {
34
6
  return wrap(String(string).normalize().replace(/\r\n/g, "\n"), columns, options);
35
7
  }
@@ -90,13 +62,6 @@ export class UI {
90
62
  return { text, padding: this.measurePadding(text) };
91
63
  }
92
64
  measurePadding(str) {
93
- // An unanchored `\s*$` was the upstream spelling, and it is quadratic: the engine
94
- // retries at every position, so a cell of 50,000 spaces then an `x` costs 1,346 ms
95
- // here — CodeQL alert 35, "polynomial regular expression used on uncontrolled data",
96
- // raised once `stripAnsi` became library input. Spaces, not the tabs the alert names:
97
- // a tab routes into `applyLayoutDSL`, which splits on it long before this runs.
98
- // `trim{Start,End}` remove exactly the set `\s` matches (WhiteSpace + LineTerminator)
99
- // and are linear, so this is the same measurement without the backtracking.
100
65
  const noAnsi = stripAnsi(str);
101
66
  return [
102
67
  0,
@@ -222,21 +187,6 @@ export class UI {
222
187
  return widths.map((w, i) => w === undefined ? Math.max(unsetWidth, minWidth(row[i])) : w);
223
188
  }
224
189
  }
225
- /*
226
- * `str.replace(/ +$/, "")` was the upstream spelling, and it is the same quadratic shape
227
- * `measurePadding` had: the start is unanchored, so the engine retries the match at every
228
- * position in the run of spaces and each attempt walks to the end before failing on the
229
- * character that is not the end. A row built from a cell of 50,000 spaces then an `x` is
230
- * 100,001 characters of which the first 50,000 are the left padding, and trimming it cost
231
- * 1,049 ms of `toString()`'s 1,223 ms. Doubling the cell quadrupled it.
232
- *
233
- * `trimEnd()` is linear but not the same function — it also removes tabs, newlines and the
234
- * rest of `\s`. A trailing tab does reach here: with `wrap: false`, `rasterize` only splits
235
- * the cell on newlines, so nothing expands the tab and nothing routes the string through
236
- * `applyLayoutDSL` (that check is behind `this.wrap`). `cliui({ wrap: false }).div('a\t')`
237
- * renders `'a\t'` today and would render `'a'` under `trimEnd`, and the yargs usage tests
238
- * compare whole help screens. This removes exactly U+0020, exactly as the regex did.
239
- */
240
190
  function trimTrailingSpaces(str) {
241
191
  let end = str.length;
242
192
  while (end > 0 && str[end - 1] === " ")
@@ -261,8 +211,6 @@ function minWidth(col) {
261
211
  return min;
262
212
  }
263
213
  function getWindowWidth() {
264
- // `host.columns` carries the upstream's guard on the process global itself, so a bundle
265
- // that has no process at all still falls back to 80 rather than throwing.
266
214
  return host.columns || 80;
267
215
  }
268
216
  function alignRight(str, width) {
@@ -282,4 +230,3 @@ function alignCenter(str, width) {
282
230
  export function cliui(opts) {
283
231
  return new UI({ width: opts?.width || getWindowWidth(), wrap: opts?.wrap });
284
232
  }
285
- //# sourceMappingURL=cliui.js.map
@@ -1,8 +1,3 @@
1
- /**
2
- * yargs' command instance — `.command()` in its five shapes, `.commandDir()`, the
3
- * builder/handler pipeline, positionals and the default command — ported for
4
- * `burgee/yargs`.
5
- */
6
1
  import { applyMiddleware, commandMiddlewareFactory } from './middleware.js';
7
2
  import { isPromise, maybeAsyncResult, parseCommand } from './utils.js';
8
3
  const DEFAULT_MARKER = /(^\*)|(^\$0)/;
@@ -227,7 +222,6 @@ export class CommandInstance {
227
222
  yargs.getInternalMethods().getUsageInstance().fail(null, error);
228
223
  }
229
224
  catch {
230
- // the failure was reported; yargs swallows the rethrow here
231
225
  }
232
226
  });
233
227
  }
@@ -418,4 +412,3 @@ function isCommandBuilderOptionDefinitions(builder) {
418
412
  export function isCommandHandlerDefinition(cmd) {
419
413
  return typeof cmd === 'object' && !Array.isArray(cmd);
420
414
  }
421
- //# sourceMappingURL=command.js.map
@@ -1,7 +1,3 @@
1
- /**
2
- * yargs' completion — `--get-yargs-completions`, the custom completion function in its
3
- * three arities, and the bash/zsh script templates — ported for `burgee/yargs`.
4
- */
5
1
  import { isCommandBuilderCallback } from './command.js';
6
2
  import { isPromise, parseCommand } from './utils.js';
7
3
  export const completionShTemplate = `###-begin-{{app_name}}-completions-###
@@ -273,4 +269,3 @@ function isSyncCompletionFunction(fn) {
273
269
  function isFallbackCompletionFunction(fn) {
274
270
  return fn.length > 3;
275
271
  }
276
- //# sourceMappingURL=completion.js.map
@@ -1,14 +1,6 @@
1
- /**
2
- * yargs' `YargsInstance`, ported method for method from yargs 18 and graded by yargs'
3
- * own suite through `compat-oracle`. Every public method, its argsert contract, the
4
- * parse pipeline, the freeze/unfreeze bookkeeping around `.parse()` and the
5
- * `getInternalMethods()` seam are the upstream's — that is what makes a user's
6
- * existing program run unchanged (J2).
7
- */
8
1
  var _a;
9
2
  import { ExitCode } from '../exit-code.js';
10
3
  import { Manifest } from '../manifest.js';
11
- import { serveMcp } from '../mcp.js';
12
4
  import { machineJson, schemaOf } from '../schema.js';
13
5
  import { tokenizeArgString } from '../yargs-parser.js';
14
6
  import { projectManifest, render } from './burgee.js';
@@ -71,7 +63,6 @@ export class YargsInstance {
71
63
  #usageConfig = {};
72
64
  #versionOpt = null;
73
65
  #validation;
74
- // ───── burgee: the manifest projection, plugins, --json, the surfaces and the seam ─────
75
66
  #burgee = undefined;
76
67
  #effects = undefined;
77
68
  #manifest = undefined;
@@ -82,7 +73,6 @@ export class YargsInstance {
82
73
  this.#parentRequire = parentRequire;
83
74
  this.#globalMiddleware = new GlobalMiddleware(this);
84
75
  this.$0 = this.#getDollarZero();
85
- // kReset builds the four collaborators; the definite assignments below are its result.
86
76
  this.#options = undefined;
87
77
  this.#usage = undefined;
88
78
  this.#validation = undefined;
@@ -602,8 +592,6 @@ export class YargsInstance {
602
592
  argsert('[string|array] [function|boolean|object] [function]', [args, shortCircuit, _parseFn], arguments.length);
603
593
  if (shortCircuit === true)
604
594
  return this.#parse(args, shortCircuit, _parseFn);
605
- // burgee: --json and the seam are per parse. What this parse turns on (json, an exit
606
- // already reported) is put back afterwards, so the next parse starts as the program left it.
607
595
  const before = this.#burgee === undefined ? undefined : { ...this.#burgee };
608
596
  const restore = () => {
609
597
  this.#burgee = before;
@@ -622,8 +610,6 @@ export class YargsInstance {
622
610
  throw err;
623
611
  }
624
612
  }
625
- // The seam: the whole run settles to one E1 exit. yargs reports its own failures
626
- // through exit(); a handler that throws synchronously is the one thing that escapes it.
627
613
  seam.exited = false;
628
614
  const finish = (argv) => {
629
615
  if (!this.#burgee?.exited)
@@ -675,8 +661,6 @@ export class YargsInstance {
675
661
  if (!shortCircuit) {
676
662
  const served = this.#burgeeSurface(args);
677
663
  if (served !== false) {
678
- // A surface was (or is being) served: the argv handed back is the short-circuit parse,
679
- // as after --help. Completions and --mcp load lazily, so those two return a promise.
680
664
  const settle = () => {
681
665
  const argv = this.#runYargsParserAndExecuteCommands(args, true);
682
666
  this.#unfreeze();
@@ -920,7 +904,6 @@ export class YargsInstance {
920
904
  delete argv['--'];
921
905
  }
922
906
  catch {
923
- // a frozen argv keeps its `--`; yargs ignores the failure
924
907
  }
925
908
  return argv;
926
909
  }
@@ -941,8 +924,6 @@ export class YargsInstance {
941
924
  const burgee = this.#burgee;
942
925
  const line = args.join(' ');
943
926
  if (burgee?.json) {
944
- // Under --json the failure is one envelope on stdout; the help screen and the
945
- // message yargs prints on the way are kept only as the envelope's message.
946
927
  if (line.trim() !== '')
947
928
  burgee.lastError = line;
948
929
  }
@@ -1060,7 +1041,6 @@ export class YargsInstance {
1060
1041
  obj = JSON.parse(this.#shim.readFileSync(pkgJsonPath, 'utf8'));
1061
1042
  }
1062
1043
  catch {
1063
- // no package.json above: version reads 'unknown', as upstream
1064
1044
  }
1065
1045
  this.#pkgs[npath] = obj || {};
1066
1046
  return this.#pkgs[npath];
@@ -1154,32 +1134,19 @@ export class YargsInstance {
1154
1134
  runHandler: this.#runHandler.bind(this),
1155
1135
  };
1156
1136
  }
1157
- // ───── burgee: additive, and guarded so a program that asks for none of it runs as on yargs ─────
1158
- /**
1159
- * The manifest every surface reads (J7, J8). Projected on each access from what the
1160
- * program registered; a command's builder is run on a scratch instance to learn its
1161
- * options, exactly as yargs' own completion does. Plugin-contributed nodes are kept.
1162
- */
1163
1137
  get manifest() {
1164
1138
  this.#manifest ??= new Manifest();
1165
1139
  projectManifest(this.#manifest, this.#snapshot());
1166
1140
  return this.#manifest;
1167
1141
  }
1168
- /** burgee: declare what the command does to the world (N6); what exposes it as an MCP tool (N2). */
1169
1142
  effects(value) {
1170
1143
  this.#effects = value;
1171
1144
  return this;
1172
1145
  }
1173
- /** Additive: plugins yargs never had. `preRun`/`postRun` fire around every handler. */
1174
1146
  use(plugin) {
1175
1147
  this.manifest.use(plugin);
1176
1148
  return this;
1177
1149
  }
1178
- /**
1179
- * Inject the streams and the exit for this instance (T1). Output goes to `stdout`/`stderr`
1180
- * instead of the console, and `exit` receives an E1 code: OK for help and version, USAGE
1181
- * for a validation failure, RUNTIME for a handler that threw.
1182
- */
1183
1150
  burgee(seam) {
1184
1151
  this.#burgee = { ...(this.#burgee ?? { json: false, lastError: '' }), ...seam };
1185
1152
  return this;
@@ -1192,7 +1159,6 @@ export class YargsInstance {
1192
1159
  let positionals = { demanded: [], optional: [] };
1193
1160
  let hasHandler = false;
1194
1161
  let description;
1195
- // The default command (`$0`, `*`) is the root's own handler, not a child path.
1196
1162
  const isDefault = (h) => /^\$0( |$)/.test(h.original);
1197
1163
  for (const [name, handler] of Object.entries(handlers)) {
1198
1164
  if (isDefault(handler))
@@ -1234,7 +1200,6 @@ export class YargsInstance {
1234
1200
  commands,
1235
1201
  };
1236
1202
  }
1237
- /** A command's snapshot: what its builder registered on the scratch, plus the command string's positionals. */
1238
1203
  #snapshotOf(handler, name) {
1239
1204
  const snap = this.#snapshot();
1240
1205
  snap.name = name;
@@ -1244,7 +1209,6 @@ export class YargsInstance {
1244
1209
  snap.version = undefined;
1245
1210
  return snap;
1246
1211
  }
1247
- /** Run a command's builder on a fresh instance, as yargs' completion does, and hand that instance back. */
1248
1212
  #childOf(handler) {
1249
1213
  const child = new _a([], this.#cwd, this.#parentRequire, this.#shim);
1250
1214
  child.#context.fullCommands.push(handler.original);
@@ -1261,11 +1225,9 @@ export class YargsInstance {
1261
1225
  }
1262
1226
  }
1263
1227
  catch {
1264
- // A builder that cannot run outside a parse projects only the command string.
1265
1228
  }
1266
1229
  return child;
1267
1230
  }
1268
- /** `--json` that the program did not declare is burgee's envelope, not an unknown option. */
1269
1231
  #takeJson(args) {
1270
1232
  const list = typeof args === 'string' ? tokenizeArgString(args) : args;
1271
1233
  const terminator = list.indexOf('--');
@@ -1277,11 +1239,6 @@ export class YargsInstance {
1277
1239
  this.#burgee = { ...(this.#burgee ?? { lastError: '' }), json: true };
1278
1240
  return [...list.slice(0, index), ...list.slice(index + 1)];
1279
1241
  }
1280
- /**
1281
- * Whether the program declared an option or command by this name — at the root, or in
1282
- * any command's builder, which the manifest projection runs to find out. Any command in
1283
- * the tree that declares the flag keeps it: the surface is additive only.
1284
- */
1285
1242
  #declares(key) {
1286
1243
  if (this.#options.key[key] || Object.values(this.#options.alias).some((list) => list.includes(key)))
1287
1244
  return true;
@@ -1289,11 +1246,6 @@ export class YargsInstance {
1289
1246
  return true;
1290
1247
  return this.manifest.commands.some((node) => Object.prototype.hasOwnProperty.call(node.options, key));
1291
1248
  }
1292
- /**
1293
- * `--schema`, `--mcp` and `completion <shell>` on a yargs-syntax program, from its
1294
- * manifest (J2). Only when the program declares none of them itself; `--schema` is
1295
- * synchronous, the other two load lazily and return a promise.
1296
- */
1297
1249
  #burgeeSurface(args) {
1298
1250
  const list = typeof args === 'string' ? tokenizeArgString(args) : args;
1299
1251
  const terminator = list.indexOf('--');
@@ -1315,11 +1267,6 @@ export class YargsInstance {
1315
1267
  });
1316
1268
  }
1317
1269
  if (head.includes('--schema') && !this.#declares('schema')) {
1318
- // R1, through the same seam the engine and the commander façade use. Hand-rolling
1319
- // `JSON.stringify(…, null, 2)` here made this façade the one front-end that could not
1320
- // see `--format=json-pretty`, and emitted a different document from the other two for
1321
- // the same CLI. `--schema` is burgee's surface, not yargs', so it answers to burgee's
1322
- // byte discipline.
1323
1270
  this.#logger.log(machineJson(schemaOf(this.manifest), head));
1324
1271
  this.exit(0);
1325
1272
  return true;
@@ -1340,14 +1287,15 @@ export class YargsInstance {
1340
1287
  return { stdout: out.join(''), stderr: err.join(''), code };
1341
1288
  };
1342
1289
  const write = this.#burgee?.stdout ?? this.#shim.process.stdout();
1343
- return serveMcp(this.manifest, { input: this.#shim.process.stdin(), output: { write: (s) => void write.write(s) }, invoke }).then(() => {
1290
+ return import('../mcp.js')
1291
+ .then(async ({ serveMcp }) => serveMcp(this.manifest, { input: this.#shim.process.stdin(), output: { write: (s) => void write.write(s) }, invoke }))
1292
+ .then(() => {
1344
1293
  this.exit(0);
1345
1294
  return true;
1346
1295
  });
1347
1296
  }
1348
1297
  return false;
1349
1298
  }
1350
- /** The handler, wrapped in the plugin hooks and followed by the envelope or the rendering. */
1351
1299
  #runHandler(handler, argv, original) {
1352
1300
  const manifest = this.#manifest;
1353
1301
  const settle = (value) => {
@@ -1368,6 +1316,10 @@ export class YargsInstance {
1368
1316
  .then(async (value) => {
1369
1317
  await manifest.fire('postRun', name, options);
1370
1318
  return settle(value);
1319
+ })
1320
+ .catch(async (cause) => {
1321
+ await manifest.fire('onError', name, options);
1322
+ throw cause;
1371
1323
  });
1372
1324
  }
1373
1325
  #settle(value, argv) {
@@ -1388,7 +1340,6 @@ export class YargsInstance {
1388
1340
  const code = err instanceof YError || err === undefined || typeof err === 'string' ? 'usage' : 'runtime';
1389
1341
  this.#logger.log(JSON.stringify({ ok: false, error: { code, message } }));
1390
1342
  }
1391
- /** burgee: where every option value came from (V3), from yargs-parser's own bookkeeping where it keeps any. */
1392
1343
  #provenance(argv) {
1393
1344
  const out = {};
1394
1345
  const defaulted = this.parsed?.defaulted ?? {};
@@ -1658,4 +1609,3 @@ _a = YargsInstance;
1658
1609
  export function isYargsInstance(y) {
1659
1610
  return !!y && typeof y.getInternalMethods === 'function';
1660
1611
  }
1661
- //# sourceMappingURL=factory.js.map
@@ -1,7 +1,3 @@
1
- /**
2
- * yargs' middleware — global, per-command, and the coerce middleware `.coerce()`
3
- * registers — ported for `burgee/yargs`.
4
- */
5
1
  import { argsert, isPromise } from './utils.js';
6
2
  export class GlobalMiddleware {
7
3
  globalMiddleware = [];
@@ -83,4 +79,3 @@ export function applyMiddleware(argv, yargs, middlewares, beforeValidation) {
83
79
  return isPromise(result) ? result.then((middlewareObj) => Object.assign(acc, middlewareObj)) : Object.assign(acc, result);
84
80
  }, argv);
85
81
  }
86
- //# sourceMappingURL=middleware.js.map
@@ -1,9 +1,3 @@
1
- /**
2
- * yargs' Node platform shim — the one object every yargs module reaches the platform
3
- * through — built from burgee's own ports of its dependencies (J9). Anything that
4
- * yargs 18 took from `cliui`, `escalade`, `get-caller-file`, `string-width`, `y18n`
5
- * and `yargs-parser` is served from here.
6
- */
7
1
  import { readdirSync, readFileSync, statSync } from 'node:fs';
8
2
  import { createRequire } from 'node:module';
9
3
  import { basename, dirname, extname, join, relative, resolve } from 'node:path';
@@ -17,7 +11,6 @@ import { y18n } from './y18n.js';
17
11
  const here = fileURLToPath(import.meta.url);
18
12
  const mainFilename = here.substring(0, here.lastIndexOf('node_modules'));
19
13
  const nodeRequire = createRequire(import.meta.url);
20
- /** escalade/sync: walk up from `start`, asking `callback` at each directory. */
21
14
  function findUp(start, callback) {
22
15
  let dir = resolve('.', start);
23
16
  let tmp;
@@ -35,7 +28,6 @@ function findUp(start, callback) {
35
28
  }
36
29
  return undefined;
37
30
  }
38
- /** get-caller-file: the file that called the function that called this (v8 stack). */
39
31
  function getCallerFile(position = 2) {
40
32
  if (position >= Error.stackTraceLimit) {
41
33
  throw new TypeError(`getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: \`${position}\` and Error.stackTraceLimit was: \`${Error.stackTraceLimit}\``);
@@ -58,15 +50,6 @@ function strictEqual(actual, expected, message) {
58
50
  if (actual !== expected)
59
51
  throw new Error(message ?? `Expected values to be strictly equal:\n\n${inspect(actual)} !== ${inspect(expected)}\n`);
60
52
  }
61
- /**
62
- * Where the 29 locale files live: the package root, not beside this file.
63
- *
64
- * This was `resolve(dirname(here), '../locales')`, which was right only while this file sat
65
- * directly in `dist/`. The first directory added under `src/` made it `dist/locales`, y18n
66
- * returned the key for every string, and 14 of yargs' own 804 tests failed. Walking up to
67
- * `package.json` resolves the same from `src/`, from `dist/`, and from
68
- * `node_modules/burgee/dist/` once published — so a later move cannot repeat it.
69
- */
70
53
  const locales = resolve(dirname(findUp(here, (_dir, names) => (names.includes('package.json') ? 'package.json' : undefined)) ?? here), 'locales');
71
54
  export const shim = {
72
55
  assert: { notStrictEqual, strictEqual },
@@ -91,8 +74,6 @@ export const shim = {
91
74
  nextTick: (fn, ...args) => {
92
75
  host.nextTick(fn, ...args);
93
76
  },
94
- // Captured, as it was before the seam: `stdColumns` is a value in `PlatformShim`, not
95
- // a thunk, so yargs reads whatever this object was built with. Unchanged on purpose.
96
77
  stdColumns: typeof host.stdout.columns !== 'undefined' ? host.stdout.columns : null,
97
78
  stdin: () => host.stdin,
98
79
  stdout: () => host.stdout,
@@ -107,4 +88,3 @@ export const shim = {
107
88
  stringWidth,
108
89
  y18n: y18n({ directory: locales, updateFiles: false }),
109
90
  };
110
- //# sourceMappingURL=shim.js.map
@@ -1,8 +1,3 @@
1
- /**
2
- * yargs' usage — the help screen, `fail`, examples, epilogues, descriptions and the
3
- * version string — ported for `burgee/yargs`. Help is rendered through the cliui port,
4
- * so yargs' usage tests compare whole screens byte for byte.
5
- */
6
1
  import { objFilter, setBlocking, YError } from './utils.js';
7
2
  function isBoolean(fail) {
8
3
  return typeof fail === 'boolean';
@@ -60,8 +55,6 @@ export function usage(yargs, shim) {
60
55
  }
61
56
  }
62
57
  err = err || new YError(msg);
63
- // The error rides along so an injected exit (burgee's seam) can tell a usage failure
64
- // from a handler's; without a seam yargs exits the process and it is unobservable.
65
58
  if (yargs.getExitProcess())
66
59
  return yargs.exit(1, err);
67
60
  else if (yargs.getInternalMethods().hasParseCallback())
@@ -484,4 +477,3 @@ function getIndentation(text) {
484
477
  function getText(text) {
485
478
  return isIndentedText(text) ? text.text : text;
486
479
  }
487
- //# sourceMappingURL=usage.js.map
@@ -1,9 +1,3 @@
1
- /**
2
- * yargs' small internal modules — yerror, parse-command, argsert, obj-filter, is-promise,
3
- * levenshtein, maybe-async-result, set-blocking, apply-extends, process-argv — ported
4
- * for `burgee/yargs`. Its suite imports four of these by their upstream file paths; the
5
- * oracle shims those paths to this entry, so the names here are the upstream names.
6
- */
7
1
  import { readFileSync } from 'node:fs';
8
2
  import { createRequire } from 'node:module';
9
3
  import { dirname, resolve } from 'node:path';
@@ -165,10 +159,6 @@ export function getProcessArgvBin() {
165
159
  }
166
160
  const nodeRequire = createRequire(import.meta.url);
167
161
  let previouslyVisitedConfigs = [];
168
- /**
169
- * `extends` in a config object. The upstream resolves a bare specifier with
170
- * `import.meta.resolve` and then loads it through `require`; both are done from here.
171
- */
172
162
  export function applyExtends(config, cwd, mergeExtends) {
173
163
  let defaultConfig = {};
174
164
  if (Object.prototype.hasOwnProperty.call(config, 'extends')) {
@@ -218,4 +208,3 @@ function mergeDeep(config1, config2) {
218
208
  export function objectKeys(object) {
219
209
  return Object.keys(object);
220
210
  }
221
- //# sourceMappingURL=utils.js.map
@@ -1,8 +1,3 @@
1
- /**
2
- * yargs' validation — demanded options and commands, unknown arguments under strict
3
- * modes, choices, implications, conflicts, and `recommendCommands` — ported for
4
- * `burgee/yargs`. Every message is the upstream's through y18n.
5
- */
6
1
  import { argsert, levenshtein as distance, objFilter } from './utils.js';
7
2
  const specialKeys = ['$0', '--', '_'];
8
3
  export function validation(yargs, usage, shim) {
@@ -264,4 +259,3 @@ export function validation(yargs, usage, shim) {
264
259
  };
265
260
  return self;
266
261
  }
267
- //# sourceMappingURL=validation.js.map
@@ -1,8 +1,3 @@
1
- /**
2
- * y18n 5 — yargs' string table — ported for `burgee/yargs`. The 29 locales ship with
3
- * burgee under `locales/`, read on first use of a locale, never written (yargs runs
4
- * y18n with `updateFiles: false`).
5
- */
6
1
  import { readFileSync, statSync } from 'node:fs';
7
2
  import { resolve } from 'node:path';
8
3
  import { format } from 'node:util';
@@ -120,4 +115,3 @@ export function y18n(opts) {
120
115
  locale: table.locale,
121
116
  };
122
117
  }
123
- //# sourceMappingURL=y18n.js.map