@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
247 lines • 11.8 kB
TypeScript
import type { CommandFnResult, Context } from '../../../config.ts';
import type { FlagView } from '../../../spec/flag_view.ts';
import { type GitError } from './errors.ts';
import { PathSpec } from '../../../../types.ts';
import type { Files } from '../../../../workspace/files.ts';
export declare const STDOUT = "stdout";
export declare const STDERR = "stderr";
export declare const MARKER = "--";
/**
* Where repository discovery begins for this invocation.
*
* `-C` changes directory before anything else happens, git's own reading of the
* option. It needs no separate session-cwd fact: the option is declared with a
* `'.'` default, and a PATH default lands as if typed, so an absent `-C`
* resolves to the session cwd and a relative `-C build` is already absolute by
* the time it arrives.
*
* Keep the PathSpec until the directory walk is checked. Repository-relative
* pathspec matching uses its virtual spelling after that check.
*
* @param fl spec-validated view over the leaf's flag bag
*/
export declare function startPoint(fl: FlagView): PathSpec;
/**
* The revision operand a verb was given, or git's own default.
*
* @param texts positional text operands
* @param fallback what an absent operand means
*/
export declare function revisionArg(texts: readonly string[], fallback?: string): string;
/**
* The words a `--` on the line marked as operands, not options.
*
* `--` is exactly how a caller names a file whose name begins with a dash, and
* git says so in every synopsis that ends `[--] [<pathspec>...]`: `git rm
* -draft` is a refused switch and `git rm -- -draft` removes the file. The
* parser consumes the marker, so the words themselves are what carries the fact
* forward, read back off the verbatim argv the record already holds.
*
* A set is enough. A dash word before the marker was read as an option and
* never reached the operands, so a word that is here and also spelled earlier on
* the line is still the escaped one.
*
* @param argv the line's verbatim tokens after the head word, subcommand words
* included
*/
export declare function escaped(argv: readonly string[]): Set<string>;
/**
* The operands before a `--` on the line and the ones after it.
*
* `git diff A B -- docs` reads what comes before the marker as revisions and
* what follows as pathspecs, whatever either looks like. Every word after the
* marker is an operand, so they are the tail of the operands, as many as the
* verbatim argv holds past it.
*
* @param texts positional text operands, as typed
* @param argv the line's verbatim tokens after the head word, subcommand words
* included
*/
export declare function splitMarked(texts: readonly string[], argv: readonly string[]): [string[], string[]];
/**
* The first operand that is really an option this build lacks.
*
* A verb taking a revision accepts free text, so every flag mirage does not
* declare reaches it as one. Resolving it as a revision is the wrong answer
* twice over: it fails, and it fails saying the repository has no such commit,
* when what happened is that mirage has no such flag. Found here, before any
* object is read, so the refusal names the real problem.
*
* Unless the caller said otherwise. A word after `--` is an operand by the
* caller's own instruction whatever it starts with, so it is never read as an
* option here; see `escaped`, which is where the marker survives the parser.
*
* Which side of the marker an operand fell on says nothing about what it
* *means* here. `diff`, `show`, `diff-tree` and the walks (`log`, `rev-list`,
* `shortlog`) read what follows the marker as pathspecs (`splitMarked`).
*
* @param texts positional text operands, as typed
* @param marked operands a `--` on the line escaped
* @param known the verb's one-letter switches, which narrow a refused cluster to
* its first unknown letter the way parse-options does; absent names the whole
* word
*/
export declare function offending(texts: readonly string[], marked?: ReadonlySet<string>, known?: ReadonlySet<string>): string | null;
/**
* The first operand that is really an option, once `-h` is out.
*
* `-h` asks for the verb's usage block, which git prints on stdout for most
* verbs and on stderr for a few (`diff`); every other word is the caller's to
* refuse in the verb's own words. See `offending` for which words count.
*
* @param ctx the line's context, carrying its leaf
* @param texts positional text operands, as typed
* @param helpStream where `-h` puts the usage block
* @throws UsageError the line asked for the usage block
*/
export declare function optionOperand(ctx: Context, texts: readonly string[], helpStream?: typeof STDOUT | typeof STDERR): string | null;
/**
* Where `-h` puts the usage block for a verb that takes it as help only alone.
*
* `rev-list`, `rev-parse` and `diff-tree` print it on stdout, exiting 0, when
* `-h` is their one word, and beside anything else on stderr as a refusal,
* exiting 129 (git 2.56).
*
* @param ctx the line's context, carrying its leaf
* @param texts the verb's positional text operands
*/
export declare function loneHelp(ctx: Context, texts: readonly string[]): typeof STDOUT | typeof STDERR;
/**
* Refuse an operand that is really an option, as an unrecognized argument.
*
* For the verbs git words without a usage block (`log`, `show`, `reflog`),
* whose refusal names the whole word (git 2.50.1).
*
* @param ctx the line's context, carrying its leaf
* @param texts positional text operands, as typed
* @param helpStream where `-h` puts the usage block
*/
export declare function checkOperands(ctx: Context, texts: readonly string[], helpStream?: typeof STDOUT | typeof STDERR): void;
/**
* The verb's usage block, as parse-options prints it.
*
* @param ctx the line's context, carrying its leaf
*/
export declare function verbUsage(ctx: Context): string;
/**
* Refuse an operand that is really an option, as parse-options does.
*
* The verbs built on parse-options (`status`, `add`, `branch`, `commit` and
* most others) name an unknown option or switch and follow it with the usage
* block, refuse a boolean handed a value on one line, and print the usage block
* on stdout for `-h`; see `gitOptionRefusal`. Measured on git 2.50.1.
*
* @param ctx the line's context, carrying its leaf
* @param texts positional text operands, as typed
*/
export declare function checkSwitches(ctx: Context, texts: readonly string[]): void;
/**
* The one-letter switches the leaf declares, without their dash.
*
* Read off the spec the line was parsed against, so the set is the verb's
* own and never a copy of it; empty where no executor built the record.
*
* @param ctx the line's context, carrying its leaf
*/
export declare function switches(ctx: Context): ReadonlySet<string>;
/**
* The part of a dash word parse-options would refuse.
*
* git reads a short cluster letter by letter, consumes the ones the verb
* declares and stops at the first it does not, so `git mv -nx` says `x' and
* `git mv -draft` says `d' (git 2.50.1); a verb that declares no switch at
* all (`reset`) still names the first letter. A long option is refused as
* typed, and so is a cluster for a verb that hands over no set: log, show
* and diff word the whole argument.
*
* @param text the dash word as the user spelled it
* @param known the verb's one-letter switches, absent for a verb that
* refuses the word whole
*/
export declare function offendingSwitch(text: string, known: ReadonlySet<string> | undefined): string;
/**
* The session's files, which every verb reads and writes through. Only a leaf
* called directly, outside a workspace, has none; git words that the way it
* words a bare repository. Mirrors Python's `require_vfs`.
*/
export declare function requireVfs(ctx: Context): Files;
/**
* Render a git error: `<prefix>: <message>`, on its own stream.
*
* git uses 128 for a fatal, which is neither the dispatcher's usage exit (2) nor
* its generic handler-error exit (1), so leaves return the code rather than
* throwing into the catch-all. A refused option carries its own prefix and code
* instead, which is git's own split, and a refusal that is really a report
* ("nothing to commit") carries no prefix and goes to stdout.
*
*
* An error carrying a `report` puts that on stdout beside the stderr line,
* because git writes some refusals to both streams at once: `<path>: needs
* merge` is the diagnosis and "you need to resolve your current index first" is
* the refusal.
*
* @param exc the error to render
*/
export declare function fatal(exc: GitError): CommandFnResult;
/**
* A config boolean read the way git's config callbacks read one.
*
* Every occurrence is parsed and the last one wins, so a value git cannot read
* fails even when a later line would have read fine. A value is
* `true`/`yes`/`on` or `false`/`no`/`off` in any case, empty for false, or an
* integer for whether it is nonzero (pinned against git 2.54).
*
* @param values every value the variable takes, in file order; a bare name
* arrives as `true`
* @param key the variable, section and name lowercased
* @param fallback the answer when the variable is unset
*/
export declare function gitBool(values: readonly string[], key: string, fallback: boolean): boolean;
/**
* A config boolean as git reads it: `true`/`yes`/`on` or `false`/`no`/`off`
* in any case, empty for false, or an integer for whether it is nonzero; null
* for anything else, which each caller answers in its own way.
*
* @param value the value as typed or as the config spells it
*/
export declare function maybeBool(value: string): boolean | null;
/**
* One `[section "name"]` block the way git's config writer spells it.
*
* The subsection escapes `"` and `\`; a value escapes those plus newline and
* tab, and is quoted when it starts or ends with a space or holds `;` or `#`.
* A branch may be named `a"b` or `a#b`, and either one written raw reads back
* as a different name (pinned against git 2.50.1).
*
* @param section the section, e.g. `branch`
* @param name the subsection, e.g. the branch name
* @param pairs variables and values, in order
*/
export declare function configSection(section: string, name: string, pairs: readonly (readonly [string, string])[]): string;
/**
* A config's text with every block for `section.name` taken out.
*
* `git branch -d` drops the deleted branch's settings this way, so a branch
* made again under the same name starts with no upstream rather than with two.
* A header names the block the way git matches it,
* spelled exactly: `[branch "x"]` with its escapes, or the older `[branch.x]`.
* `[Branch "x"]` and `[branch.X]` are left, as git leaves them, and a line
* opening with `[` ends a block (pinned against git 2.50.1).
*
* With `keys` only those variables leave the blocks, and a block they leave
* holding no variable leaves with them, header and all, as
* `git branch --delete-merged` clears an upstream (git 2.56.0). A variable
* sharing its header's line leaves the header behind.
*
* A value continued onto the next line by a trailing backslash is followed, so
* a continuation that opens with `[` is still part of the block. git 2.50.1
* reads it as a header there and leaves the rest of the block behind, which it
* then refuses as a bad config line; mirage keeps the file readable instead.
*
* @param text the config file's contents
* @param section the section as git writes it, e.g. `branch`
* @param name the subsection, e.g. the branch name
* @param keys the variables to take out, lowercase; null takes the whole block
*/
export declare function withoutSection(text: string, section: string, name: string, keys?: ReadonlySet<string> | null): string;
//# sourceMappingURL=util.d.ts.map