@mcuste/pi-herdr-worktree 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +137 -0
- package/dist/argument.d.ts +54 -0
- package/dist/argument.d.ts.map +1 -0
- package/dist/argument.js +101 -0
- package/dist/argument.js.map +1 -0
- package/dist/capability.d.ts +30 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +154 -0
- package/dist/capability.js.map +1 -0
- package/dist/guidance.d.ts +22 -0
- package/dist/guidance.d.ts.map +1 -0
- package/dist/guidance.js +20 -0
- package/dist/guidance.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/process.d.ts +33 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +91 -0
- package/dist/process.js.map +1 -0
- package/dist/response.d.ts +52 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +129 -0
- package/dist/response.js.map +1 -0
- package/dist/tools.d.ts +79 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +555 -0
- package/dist/tools.js.map +1 -0
- package/dist/worktree.d.ts +16 -0
- package/dist/worktree.d.ts.map +1 -0
- package/dist/worktree.js +47 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +89 -0
- package/src/argument.ts +183 -0
- package/src/capability.ts +223 -0
- package/src/guidance.ts +51 -0
- package/src/index.ts +5 -0
- package/src/process.ts +144 -0
- package/src/response.ts +189 -0
- package/src/tools.ts +952 -0
- package/src/worktree.ts +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mcuste
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# pi-herdr-worktree
|
|
2
|
+
|
|
3
|
+
[](https://github.com/mcuste/pi-herdr-worktree/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@mcuste/pi-herdr-worktree)
|
|
5
|
+
|
|
6
|
+
An extension for the [Pi](https://github.com/earendil-works/pi) and
|
|
7
|
+
[Oh My Pi](https://github.com/can1357/oh-my-pi) terminal coding agents. It gives the model one
|
|
8
|
+
`herdr_worktree` tool that runs a fixed set of [Herdr](https://herdr.dev) Git worktree operations,
|
|
9
|
+
instead of letting it type `herdr` commands into a shell.
|
|
10
|
+
|
|
11
|
+
If any of those names are new to you:
|
|
12
|
+
|
|
13
|
+
- **Herdr** is a terminal workspace manager for coding agents. It can back a workspace with a Git
|
|
14
|
+
worktree, so a branch gets its own checkout, its own tabs, and its own panes.
|
|
15
|
+
- **Pi** and **Oh My Pi** are terminal coding agents. An **extension** is an npm package they load
|
|
16
|
+
at startup to add tools the model can call.
|
|
17
|
+
|
|
18
|
+
## Why
|
|
19
|
+
|
|
20
|
+
An agent with shell access can already run `herdr`, but a shell gives it a free-form command
|
|
21
|
+
string. Herdr's CLI does not accept `--flag=value`, so every value is a separate argument, and a
|
|
22
|
+
value that starts with `-` silently becomes a flag. A wrong `--workspace` deletes the wrong
|
|
23
|
+
checkout, `--force` throws away uncommitted work, and `--focus` moves the user's view away from
|
|
24
|
+
what they were doing.
|
|
25
|
+
|
|
26
|
+
This extension replaces that with a closed set of operations. Each one accepts only its own typed
|
|
27
|
+
fields, builds a fixed argument array, checks the repository before running, and verifies the
|
|
28
|
+
result against Git afterwards. There is no shell string anywhere.
|
|
29
|
+
|
|
30
|
+
## Requirements
|
|
31
|
+
|
|
32
|
+
- Node.js 22 or newer
|
|
33
|
+
- Git 2.36 or newer
|
|
34
|
+
- Herdr 0.8.2 or newer, and an agent running inside a Herdr-managed pane
|
|
35
|
+
|
|
36
|
+
The extension loads anywhere. Outside a Herdr pane, outside a Git work tree, or without the
|
|
37
|
+
`herdr` CLI, a tool call fails with an explanatory error rather than running an unsupported
|
|
38
|
+
command.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
Pi:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pi install npm:@mcuste/pi-herdr-worktree
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Oh My Pi:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
omp plugin install @mcuste/pi-herdr-worktree
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or through the Oh My Pi marketplace:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
/marketplace add mcuste/pi-herdr-worktree
|
|
58
|
+
/marketplace install pi-herdr-worktree@pi-herdr-worktree
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
From a local checkout:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pnpm install
|
|
65
|
+
pi install /absolute/path/to/pi-herdr-worktree
|
|
66
|
+
omp plugin link /absolute/path/to/pi-herdr-worktree
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## What the tool does
|
|
70
|
+
|
|
71
|
+
One tool named `herdr_worktree`, selected by an `operation` field:
|
|
72
|
+
|
|
73
|
+
| Operation | Runs | Purpose |
|
|
74
|
+
| --- | --- | --- |
|
|
75
|
+
| `list` | `herdr worktree list` | Read every worktree of the current repository |
|
|
76
|
+
| `create` | `herdr worktree create` | Add a worktree on a new branch and open it as a workspace |
|
|
77
|
+
| `open` | `herdr worktree open` | Open an existing worktree as a workspace |
|
|
78
|
+
| `remove` | `herdr worktree remove` | Delete a worktree checkout and close its workspace |
|
|
79
|
+
|
|
80
|
+
`list` is read-only. The other three change the repository and the session, and Oh My Pi asks for
|
|
81
|
+
execute approval; `remove` always prompts, and so does a `create` that names its own `path`. Full
|
|
82
|
+
per-operation fields and guarantees are in [docs/operations.md](docs/operations.md).
|
|
83
|
+
|
|
84
|
+
## System prompt note
|
|
85
|
+
|
|
86
|
+
The tool loads on demand, so its description is not in the base prompt. The model can reach for
|
|
87
|
+
`herdr` or `git worktree` in a shell before it sees the tool, so the extension appends one note to
|
|
88
|
+
the system prompt at the start of each turn:
|
|
89
|
+
|
|
90
|
+
> Use the herdr_worktree tool for Git worktrees, not herdr or git worktree in bash. Create a
|
|
91
|
+
> worktree when work needs its own checkout, for example parallel multi-agent work.
|
|
92
|
+
|
|
93
|
+
The note is added once per prompt, only where detection succeeds, and only in a host that offers
|
|
94
|
+
the `before_agent_start` event. A host without that event still gets the tool.
|
|
95
|
+
|
|
96
|
+
Detection reads `HERDR_ENV` first. That variable belongs to the process, so outside Herdr the
|
|
97
|
+
extension starts no child process at all. Inside a Herdr pane, detection also finds the Git
|
|
98
|
+
repository and reads the `herdr` version, then caches the result in memory for ten minutes. A
|
|
99
|
+
failed detection is cached for five minutes, so a directory that is not a Git work tree does not
|
|
100
|
+
run `git` and `herdr` on every turn.
|
|
101
|
+
|
|
102
|
+
## What is deliberately missing
|
|
103
|
+
|
|
104
|
+
- **Workspace, tab, pane, and agent control** (`herdr workspace`, `herdr tab`, `herdr pane`,
|
|
105
|
+
`herdr agent`) is a separate concern. This extension only manages worktree-backed workspaces.
|
|
106
|
+
- **Session and server control** (`herdr session`, `herdr server`, `herdr update`) can stop the
|
|
107
|
+
user's session and every process in it.
|
|
108
|
+
- **`herdr worktree remove` without a verified target.** The tool always lists the repository's
|
|
109
|
+
worktrees first and refuses a workspace that does not hold a linked worktree of it.
|
|
110
|
+
|
|
111
|
+
For anything else, the model works through the normal Herdr workflow with the user in the loop.
|
|
112
|
+
|
|
113
|
+
## Safety
|
|
114
|
+
|
|
115
|
+
Every operation checks the repository before and after it runs: a new worktree must be registered
|
|
116
|
+
by Git on the requested branch, an opened worktree must be the one that was asked for, and a
|
|
117
|
+
removed checkout must be gone from `git worktree list`. A failed check is reported as an uncertain
|
|
118
|
+
result rather than retried.
|
|
119
|
+
|
|
120
|
+
Arguments are never concatenated into a shell command. Herdr does not accept `--flag=value`, so
|
|
121
|
+
every value travels as its own argument and is rejected before spawning if it starts with `-`. Each
|
|
122
|
+
value also carries the option it was parsed for, so a label cannot arrive as a branch. See
|
|
123
|
+
[docs/safety.md](docs/safety.md).
|
|
124
|
+
|
|
125
|
+
Focus defaults to off. The tool passes `--no-focus` unless the caller explicitly asks to move the
|
|
126
|
+
user's view.
|
|
127
|
+
|
|
128
|
+
## Documentation
|
|
129
|
+
|
|
130
|
+
- [Operations reference](docs/operations.md)
|
|
131
|
+
- [Safety model](docs/safety.md)
|
|
132
|
+
- [Development and release](docs/development.md)
|
|
133
|
+
- [Changelog](CHANGELOG.md)
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type CommandRunner } from "./process.js";
|
|
2
|
+
export declare const MAX_BRANCH_NAME_LENGTH = 255;
|
|
3
|
+
export declare const MAX_PATH_LENGTH = 4096;
|
|
4
|
+
export declare const MAX_LABEL_LENGTH = 120;
|
|
5
|
+
export declare const MIN_WORKSPACE_ID_LENGTH = 2;
|
|
6
|
+
export declare const MAX_WORKSPACE_ID_LENGTH = 17;
|
|
7
|
+
declare const branchNameBrand: unique symbol;
|
|
8
|
+
declare const revisionBrand: unique symbol;
|
|
9
|
+
declare const commitIdBrand: unique symbol;
|
|
10
|
+
declare const absolutePathBrand: unique symbol;
|
|
11
|
+
declare const labelBrand: unique symbol;
|
|
12
|
+
declare const workspaceIdBrand: unique symbol;
|
|
13
|
+
/** The branch name `git check-ref-format --branch` printed, so shorthand is already expanded. */
|
|
14
|
+
export type ParsedBranchName = string & {
|
|
15
|
+
readonly [branchNameBrand]: true;
|
|
16
|
+
};
|
|
17
|
+
/** A revision that `git rev-parse --verify` resolved to a commit. */
|
|
18
|
+
export type ParsedRevision = string & {
|
|
19
|
+
readonly [revisionBrand]: true;
|
|
20
|
+
};
|
|
21
|
+
/** A full object id that `git rev-parse` printed. */
|
|
22
|
+
type ParsedCommitId = string & {
|
|
23
|
+
readonly [commitIdBrand]: true;
|
|
24
|
+
};
|
|
25
|
+
export type ParsedAbsolutePath = string & {
|
|
26
|
+
readonly [absolutePathBrand]: true;
|
|
27
|
+
};
|
|
28
|
+
export type ParsedLabel = string & {
|
|
29
|
+
readonly [labelBrand]: true;
|
|
30
|
+
};
|
|
31
|
+
export type ParsedWorkspaceId = string & {
|
|
32
|
+
readonly [workspaceIdBrand]: true;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Every value that may become a command argument. A plain string is not a member, so unparsed
|
|
36
|
+
* text cannot reach a spawned command.
|
|
37
|
+
*/
|
|
38
|
+
export type ParsedArgumentValue = ParsedAbsolutePath | ParsedBranchName | ParsedLabel | ParsedRevision | ParsedWorkspaceId;
|
|
39
|
+
/** A revision, together with the commit it pointed at when it was parsed. */
|
|
40
|
+
export interface ParsedBase {
|
|
41
|
+
readonly revision: ParsedRevision;
|
|
42
|
+
readonly commit: ParsedCommitId;
|
|
43
|
+
}
|
|
44
|
+
/** The runtime re-check of what the parsed types already promise, for the gate before a spawn. */
|
|
45
|
+
export declare function hasParsedArgumentSyntax(value: unknown): value is string;
|
|
46
|
+
export declare function parseBranchName(runner: CommandRunner, value: unknown, label: string, cwd: string, signal: AbortSignal | undefined): Promise<ParsedBranchName>;
|
|
47
|
+
/** A base for a new worktree only has to resolve to a commit, so tags and SHAs are allowed. */
|
|
48
|
+
export declare function parseBase(runner: CommandRunner, value: unknown, label: string, cwd: string, signal: AbortSignal | undefined): Promise<ParsedBase>;
|
|
49
|
+
export declare function parseAbsolutePath(value: unknown, label: string): ParsedAbsolutePath;
|
|
50
|
+
/** A label is display text, so it only has to stay a single argument on one line. */
|
|
51
|
+
export declare function parseLabel(value: unknown, label: string): ParsedLabel;
|
|
52
|
+
export declare function parseWorkspaceId(value: unknown, label: string): ParsedWorkspaceId;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=argument.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argument.d.ts","sourceRoot":"","sources":["../src/argument.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,cAAc,CAAC;AAEtB,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAIpC,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,OAAO,CAAC,MAAM,eAAe,EAAE,OAAO,MAAM,CAAC;AAC7C,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,MAAM,CAAC;AAC3C,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,MAAM,CAAC;AAC3C,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,MAAM,CAAC;AAC/C,OAAO,CAAC,MAAM,UAAU,EAAE,OAAO,MAAM,CAAC;AACxC,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,MAAM,CAAC;AAE9C,iGAAiG;AACjG,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAE7E,qEAAqE;AACrE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEzE,qDAAqD;AACrD,KAAK,cAAc,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAElE,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEjF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAE/E;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAC3B,kBAAkB,GAClB,gBAAgB,GAChB,WAAW,GACX,cAAc,GACd,iBAAiB,CAAC;AAEtB,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;CACjC;AAsBD,kGAAkG;AAClG,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEvE;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CA6B3B;AAED,+FAA+F;AAC/F,wBAAsB,SAAS,CAC7B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,UAAU,CAAC,CA4BrB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAYnF;AAED,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAKrE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAKjF"}
|
package/dist/argument.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { isAbsolute, normalize } from "node:path";
|
|
2
|
+
import { CommandCancelledError, runChecked, } from "./process.js";
|
|
3
|
+
export const MAX_BRANCH_NAME_LENGTH = 255;
|
|
4
|
+
export const MAX_PATH_LENGTH = 4096;
|
|
5
|
+
export const MAX_LABEL_LENGTH = 120;
|
|
6
|
+
/** The bounds come from the pattern, so the schema advertises exactly what this accepts. */
|
|
7
|
+
const WORKSPACE_ID = /^w[0-9A-Za-z]{1,16}$/u;
|
|
8
|
+
export const MIN_WORKSPACE_ID_LENGTH = 2;
|
|
9
|
+
export const MAX_WORKSPACE_ID_LENGTH = 17;
|
|
10
|
+
/** Bidirectional marks make text display as other text, and a newline forges a line of output. */
|
|
11
|
+
const UNSAFE_CHARACTERS = /[\p{Cc}\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/u;
|
|
12
|
+
const COMMIT_ID = /^[0-9a-f]{40}(?:[0-9a-f]{24})?$/u;
|
|
13
|
+
/**
|
|
14
|
+
* Rejects values that could turn into a command-line option, split an argument, or forge a line
|
|
15
|
+
* of output before Git or Herdr ever sees them.
|
|
16
|
+
*/
|
|
17
|
+
function hasSafeArgumentSyntax(value, maxLength) {
|
|
18
|
+
return (typeof value === "string" &&
|
|
19
|
+
value.length > 0 &&
|
|
20
|
+
value.length <= maxLength &&
|
|
21
|
+
value === value.trim() &&
|
|
22
|
+
!value.startsWith("-") &&
|
|
23
|
+
!UNSAFE_CHARACTERS.test(value));
|
|
24
|
+
}
|
|
25
|
+
/** The runtime re-check of what the parsed types already promise, for the gate before a spawn. */
|
|
26
|
+
export function hasParsedArgumentSyntax(value) {
|
|
27
|
+
return hasSafeArgumentSyntax(value, MAX_PATH_LENGTH);
|
|
28
|
+
}
|
|
29
|
+
export async function parseBranchName(runner, value, label, cwd, signal) {
|
|
30
|
+
if (!hasSafeArgumentSyntax(value, MAX_BRANCH_NAME_LENGTH)) {
|
|
31
|
+
throw new Error(`${label} is not a safe branch name: ${JSON.stringify(value)}.`);
|
|
32
|
+
}
|
|
33
|
+
let result;
|
|
34
|
+
try {
|
|
35
|
+
result = await runChecked(runner, "git", ["check-ref-format", "--branch", value], { cwd, signal }, `${label} is not a valid Git branch name`);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error instanceof CommandCancelledError) {
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`${label} is not a valid Git branch name: ${JSON.stringify(value)}.`, {
|
|
42
|
+
cause: error,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// `--branch` expands shorthand such as `@{-1}`, so only the printed name names the real branch.
|
|
46
|
+
const expanded = result.stdout.trim();
|
|
47
|
+
if (!hasSafeArgumentSyntax(expanded, MAX_BRANCH_NAME_LENGTH)) {
|
|
48
|
+
throw new Error(`${label} did not expand to a safe branch name: ${JSON.stringify(value)}.`);
|
|
49
|
+
}
|
|
50
|
+
return expanded;
|
|
51
|
+
}
|
|
52
|
+
/** A base for a new worktree only has to resolve to a commit, so tags and SHAs are allowed. */
|
|
53
|
+
export async function parseBase(runner, value, label, cwd, signal) {
|
|
54
|
+
if (!hasSafeArgumentSyntax(value, MAX_BRANCH_NAME_LENGTH)) {
|
|
55
|
+
throw new Error(`${label} is not a safe Git revision: ${JSON.stringify(value)}.`);
|
|
56
|
+
}
|
|
57
|
+
let result;
|
|
58
|
+
try {
|
|
59
|
+
result = await runChecked(runner, "git", ["rev-parse", "--verify", "--quiet", `${value}^{commit}`], { cwd, signal }, `${label} does not resolve to a commit`);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof CommandCancelledError) {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
throw new Error(`${label} does not resolve to a commit: ${JSON.stringify(value)}.`, {
|
|
66
|
+
cause: error,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const commit = result.stdout.trim();
|
|
70
|
+
if (!COMMIT_ID.test(commit)) {
|
|
71
|
+
throw new Error(`${label} did not resolve to a commit id: ${JSON.stringify(value)}.`);
|
|
72
|
+
}
|
|
73
|
+
return { revision: value, commit: commit };
|
|
74
|
+
}
|
|
75
|
+
export function parseAbsolutePath(value, label) {
|
|
76
|
+
if (!hasSafeArgumentSyntax(value, MAX_PATH_LENGTH)) {
|
|
77
|
+
throw new Error(`${label} is not a safe path: ${JSON.stringify(value)}.`);
|
|
78
|
+
}
|
|
79
|
+
if (!isAbsolute(value)) {
|
|
80
|
+
throw new Error(`${label} must be an absolute path: ${JSON.stringify(value)}.`);
|
|
81
|
+
}
|
|
82
|
+
const normalized = normalize(value).replace(/\/+$/u, "");
|
|
83
|
+
if (!normalized || !isAbsolute(normalized)) {
|
|
84
|
+
throw new Error(`${label} does not normalise to an absolute path: ${JSON.stringify(value)}.`);
|
|
85
|
+
}
|
|
86
|
+
return normalized;
|
|
87
|
+
}
|
|
88
|
+
/** A label is display text, so it only has to stay a single argument on one line. */
|
|
89
|
+
export function parseLabel(value, label) {
|
|
90
|
+
if (!hasSafeArgumentSyntax(value, MAX_LABEL_LENGTH)) {
|
|
91
|
+
throw new Error(`${label} must be single-line text without leading options.`);
|
|
92
|
+
}
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
export function parseWorkspaceId(value, label) {
|
|
96
|
+
if (!hasSafeArgumentSyntax(value, MAX_WORKSPACE_ID_LENGTH) || !WORKSPACE_ID.test(value)) {
|
|
97
|
+
throw new Error(`${label} is not a Herdr workspace id: ${JSON.stringify(value)}.`);
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=argument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"argument.js","sourceRoot":"","sources":["../src/argument.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ParsedAbsolutePath } from "./argument.js";
|
|
2
|
+
import { type CommandRunner } from "./process.js";
|
|
3
|
+
export interface GitRepository {
|
|
4
|
+
readonly root: ParsedAbsolutePath;
|
|
5
|
+
readonly gitDir: ParsedAbsolutePath;
|
|
6
|
+
}
|
|
7
|
+
export interface HerdrCapability {
|
|
8
|
+
readonly repository: GitRepository;
|
|
9
|
+
readonly herdrVersion: string;
|
|
10
|
+
readonly cache: "memory" | "detected";
|
|
11
|
+
}
|
|
12
|
+
export declare class HerdrUnavailableError extends Error {
|
|
13
|
+
constructor(message: string, options?: ErrorOptions);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The capability is a property of the running session, not of the repository, so it is only
|
|
17
|
+
* held in memory. Nothing is written to the repository.
|
|
18
|
+
*/
|
|
19
|
+
export declare class HerdrCapabilityResolver {
|
|
20
|
+
#private;
|
|
21
|
+
constructor(runner?: CommandRunner, environment?: Readonly<Record<string, string | undefined>>, now?: () => number);
|
|
22
|
+
ensure(cwd: string, signal?: AbortSignal): Promise<HerdrCapability>;
|
|
23
|
+
/**
|
|
24
|
+
* Never throws, unlike `ensure`. A failed detection is cached for a short time, so a caller that
|
|
25
|
+
* runs on every agent start does not spawn `git` and `herdr` every turn.
|
|
26
|
+
*/
|
|
27
|
+
tryEnsure(cwd: string, signal?: AbortSignal): Promise<HerdrCapability | undefined>;
|
|
28
|
+
forget(cwd: string): void;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,eAAe,CAAC;AAC3E,OAAO,EAGL,KAAK,aAAa,EAGnB,MAAM,cAAc,CAAC;AAStB,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;CACrC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,CAAC;CACvC;AAOD,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAGlD;CACF;AA6BD;;;GAGG;AACH,qBAAa,uBAAuB;;IAOlC,YACE,MAAM,GAAE,aAA0B,EAClC,WAAW,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,EACvE,GAAG,GAAE,MAAM,MAAiB,EAK7B;IAEK,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAcxE;IAED;;;OAGG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAqBvF;IAED,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAWxB;CAgFF"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { parseAbsolutePath } from "./argument.js";
|
|
3
|
+
import { CommandCancelledError, runChecked, runCommand, } from "./process.js";
|
|
4
|
+
/** Herdr injects this into every managed pane. Without it there is no session to talk to. */
|
|
5
|
+
const SESSION_MARKER = "HERDR_ENV";
|
|
6
|
+
const MINIMUM_HERDR_VERSION = [0, 8, 2];
|
|
7
|
+
const CAPABILITY_MAX_AGE_MS = 10 * 60 * 1000;
|
|
8
|
+
const UNAVAILABLE_RETRY_MS = 5 * 60 * 1000;
|
|
9
|
+
export class HerdrUnavailableError extends Error {
|
|
10
|
+
constructor(message, options) {
|
|
11
|
+
super(message, options);
|
|
12
|
+
this.name = "HerdrUnavailableError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function isAtLeast(installed, minimum) {
|
|
16
|
+
for (const [index, required] of minimum.entries()) {
|
|
17
|
+
const part = installed[index] ?? 0;
|
|
18
|
+
if (part !== required) {
|
|
19
|
+
return part > required;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
function parseHerdrVersion(result) {
|
|
25
|
+
const raw = result.stdout.trim() || result.stderr.trim();
|
|
26
|
+
const match = /^(?:herdr )?(\d+)\.(\d+)\.(\d+)/u.exec(raw);
|
|
27
|
+
if (!match) {
|
|
28
|
+
throw new HerdrUnavailableError(`Unable to read the Herdr version from ${JSON.stringify(raw)}.`);
|
|
29
|
+
}
|
|
30
|
+
const parts = match.slice(1, 4).map(Number);
|
|
31
|
+
if (!isAtLeast(parts, MINIMUM_HERDR_VERSION)) {
|
|
32
|
+
throw new HerdrUnavailableError(`Herdr ${MINIMUM_HERDR_VERSION.join(".")} or newer is required, but ${parts.join(".")} is installed.`);
|
|
33
|
+
}
|
|
34
|
+
return parts.join(".");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The capability is a property of the running session, not of the repository, so it is only
|
|
38
|
+
* held in memory. Nothing is written to the repository.
|
|
39
|
+
*/
|
|
40
|
+
export class HerdrCapabilityResolver {
|
|
41
|
+
#runner;
|
|
42
|
+
#environment;
|
|
43
|
+
#now;
|
|
44
|
+
#memory = new Map();
|
|
45
|
+
#unavailable = new Map();
|
|
46
|
+
constructor(runner = runCommand, environment = process.env, now = Date.now) {
|
|
47
|
+
this.#runner = runner;
|
|
48
|
+
this.#environment = environment;
|
|
49
|
+
this.#now = now;
|
|
50
|
+
}
|
|
51
|
+
async ensure(cwd, signal) {
|
|
52
|
+
const lookupKey = resolve(cwd);
|
|
53
|
+
const remembered = this.#memory.get(lookupKey);
|
|
54
|
+
if (remembered && remembered.expiresAt > this.#now()) {
|
|
55
|
+
return { ...remembered.capability, cache: "memory" };
|
|
56
|
+
}
|
|
57
|
+
this.#memory.delete(lookupKey);
|
|
58
|
+
this.#assertManagedSession();
|
|
59
|
+
const repository = await this.#findRepository(cwd, signal);
|
|
60
|
+
const herdrVersion = await this.#detectHerdr(repository, signal);
|
|
61
|
+
const capability = { repository, herdrVersion };
|
|
62
|
+
this.#remember(lookupKey, capability);
|
|
63
|
+
return { ...capability, cache: "detected" };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Never throws, unlike `ensure`. A failed detection is cached for a short time, so a caller that
|
|
67
|
+
* runs on every agent start does not spawn `git` and `herdr` every turn.
|
|
68
|
+
*/
|
|
69
|
+
async tryEnsure(cwd, signal) {
|
|
70
|
+
// The marker comes from the process environment, so the answer cannot change while it runs.
|
|
71
|
+
if (!this.#isManagedSession()) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const lookupKey = resolve(cwd);
|
|
75
|
+
const retryAt = this.#unavailable.get(lookupKey);
|
|
76
|
+
if (retryAt !== undefined && retryAt > this.#now()) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
this.#unavailable.delete(lookupKey);
|
|
80
|
+
try {
|
|
81
|
+
return await this.ensure(cwd, signal);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
if (error instanceof HerdrUnavailableError) {
|
|
85
|
+
this.#unavailable.set(lookupKey, this.#now() + UNAVAILABLE_RETRY_MS);
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
forget(cwd) {
|
|
91
|
+
const lookupKey = resolve(cwd);
|
|
92
|
+
this.#unavailable.delete(lookupKey);
|
|
93
|
+
const remembered = this.#memory.get(lookupKey);
|
|
94
|
+
const repositoryRoot = resolve(remembered?.capability.repository.root ?? cwd);
|
|
95
|
+
for (const [key, entry] of this.#memory) {
|
|
96
|
+
if (key === lookupKey || resolve(entry.capability.repository.root) === repositoryRoot) {
|
|
97
|
+
this.#memory.delete(key);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
this.#unavailable.delete(repositoryRoot);
|
|
101
|
+
}
|
|
102
|
+
#remember(lookupKey, capability) {
|
|
103
|
+
const remembered = { capability, expiresAt: this.#now() + CAPABILITY_MAX_AGE_MS };
|
|
104
|
+
this.#memory.set(lookupKey, remembered);
|
|
105
|
+
this.#memory.set(resolve(capability.repository.root), remembered);
|
|
106
|
+
}
|
|
107
|
+
#isManagedSession() {
|
|
108
|
+
return this.#environment[SESSION_MARKER] === "1";
|
|
109
|
+
}
|
|
110
|
+
#assertManagedSession() {
|
|
111
|
+
if (!this.#isManagedSession()) {
|
|
112
|
+
throw new HerdrUnavailableError(`Herdr worktree tools only run inside a Herdr-managed pane, where ${SESSION_MARKER} is 1. Start the agent from a Herdr session and retry.`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async #findRepository(cwd, signal) {
|
|
116
|
+
let result;
|
|
117
|
+
try {
|
|
118
|
+
result = await runChecked(this.#runner, "git", ["rev-parse", "--show-toplevel", "--absolute-git-dir"], { cwd, signal }, "Unable to locate the Git repository");
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (error instanceof CommandCancelledError) {
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
throw new HerdrUnavailableError("Herdr worktree actions require a Git work tree. Run the tool from inside a Git repository.", { cause: error });
|
|
125
|
+
}
|
|
126
|
+
const lines = result.stdout.replace(/\r?\n$/u, "").split(/\r?\n/u);
|
|
127
|
+
if (lines.length !== 2) {
|
|
128
|
+
throw new HerdrUnavailableError("Git returned an invalid repository location; Herdr worktree actions cannot run reliably here.");
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
return {
|
|
132
|
+
root: parseAbsolutePath(lines[0], "The repository root"),
|
|
133
|
+
gitDir: parseAbsolutePath(lines[1], "The Git directory"),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
throw new HerdrUnavailableError("Git returned an invalid repository location; Herdr worktree actions cannot run reliably here.", { cause: error });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async #detectHerdr(repository, signal) {
|
|
141
|
+
let result;
|
|
142
|
+
try {
|
|
143
|
+
result = await runChecked(this.#runner, "herdr", ["--version"], { cwd: repository.root, signal }, "Unable to read the Herdr version");
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
if (error instanceof CommandCancelledError) {
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
throw new HerdrUnavailableError("The Herdr CLI is unavailable. Install `herdr` and ensure it is on PATH.", { cause: error });
|
|
150
|
+
}
|
|
151
|
+
return parseHerdrVersion(result);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { HerdrCapabilityResolver } from "./capability.js";
|
|
2
|
+
/**
|
|
3
|
+
* The tool loads on demand, so the model needs this note before it reaches for `herdr` or
|
|
4
|
+
* `git worktree` in bash.
|
|
5
|
+
*/
|
|
6
|
+
export declare const HERDR_PROMPT_NOTE = "Use the herdr_worktree tool for Git worktrees, not herdr or git worktree in bash. Create a worktree when work needs its own checkout, for example parallel multi-agent work.";
|
|
7
|
+
interface BeforeAgentStartEvent {
|
|
8
|
+
readonly systemPrompt?: unknown;
|
|
9
|
+
}
|
|
10
|
+
interface BeforeAgentStartContext {
|
|
11
|
+
readonly cwd?: string;
|
|
12
|
+
readonly signal?: AbortSignal;
|
|
13
|
+
}
|
|
14
|
+
interface BeforeAgentStartResult {
|
|
15
|
+
readonly systemPrompt: string;
|
|
16
|
+
}
|
|
17
|
+
export interface HerdrPromptApi {
|
|
18
|
+
on?(event: "before_agent_start", handler: (event: BeforeAgentStartEvent, context?: BeforeAgentStartContext) => Promise<BeforeAgentStartResult | undefined>): void;
|
|
19
|
+
}
|
|
20
|
+
export declare function registerHerdrGuidance(pi: HerdrPromptApi, capabilities: HerdrCapabilityResolver): void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=guidance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guidance.d.ts","sourceRoot":"","sources":["../src/guidance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,iBAAiB,iLACkJ,CAAC;AAEjL,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,CACD,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,CACP,KAAK,EAAE,qBAAqB,EAC5B,OAAO,CAAC,EAAE,uBAAuB,KAC9B,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,GAC/C,IAAI,CAAC;CACT;AAED,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,cAAc,EAClB,YAAY,EAAE,uBAAuB,GACpC,IAAI,CAeN"}
|
package/dist/guidance.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tool loads on demand, so the model needs this note before it reaches for `herdr` or
|
|
3
|
+
* `git worktree` in bash.
|
|
4
|
+
*/
|
|
5
|
+
export const HERDR_PROMPT_NOTE = "Use the herdr_worktree tool for Git worktrees, not herdr or git worktree in bash. Create a worktree when work needs its own checkout, for example parallel multi-agent work.";
|
|
6
|
+
export function registerHerdrGuidance(pi, capabilities) {
|
|
7
|
+
pi.on?.("before_agent_start", async (event, context) => {
|
|
8
|
+
const systemPrompt = event?.systemPrompt;
|
|
9
|
+
// A host may chain several handlers, so the note must not be appended twice.
|
|
10
|
+
if (typeof systemPrompt !== "string" || systemPrompt.includes(HERDR_PROMPT_NOTE)) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const capability = await capabilities.tryEnsure(context?.cwd ?? process.cwd(), context?.signal);
|
|
14
|
+
if (!capability) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
return { systemPrompt: `${systemPrompt}\n\n${HERDR_PROMPT_NOTE}` };
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=guidance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guidance.js","sourceRoot":"","sources":["../src/guidance.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAC5B,8KAA8K,CAAC;AAyBjL,MAAM,UAAU,qBAAqB,CACnC,EAAkB,EAClB,YAAqC;IAErC,EAAE,CAAC,EAAE,EAAE,CAAC,oBAAoB,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACrD,MAAM,YAAY,GAAG,KAAK,EAAE,YAAY,CAAC;QACzC,6EAA6E;QAC7E,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACjF,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAChG,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,OAAO,iBAAiB,EAAE,EAAE,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAA8B,MAAM,YAAY,CAAC;AAEhF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,iBAAiB,GAAG,IAAI,CAEnE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAqB;IAC3D,0BAA0B,CAAC,EAAE,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface CommandResult {
|
|
2
|
+
readonly command: string;
|
|
3
|
+
readonly args: readonly string[];
|
|
4
|
+
readonly exitCode: number;
|
|
5
|
+
readonly stdout: string;
|
|
6
|
+
readonly stderr: string;
|
|
7
|
+
}
|
|
8
|
+
export interface RunCommandOptions {
|
|
9
|
+
readonly cwd: string;
|
|
10
|
+
readonly signal?: AbortSignal | undefined;
|
|
11
|
+
readonly maxOutputBytes?: number | undefined;
|
|
12
|
+
}
|
|
13
|
+
export type CommandRunner = (command: string, args: readonly string[], options: RunCommandOptions) => Promise<CommandResult>;
|
|
14
|
+
export declare class CommandInvocationError extends Error {
|
|
15
|
+
readonly command: string;
|
|
16
|
+
readonly code: string | undefined;
|
|
17
|
+
constructor(command: string, message: string, code: string | undefined, options?: ErrorOptions);
|
|
18
|
+
}
|
|
19
|
+
export declare class CommandCancelledError extends Error {
|
|
20
|
+
constructor(command: string);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Node kills the child once its output passes `maxBuffer`. That is a size limit, not a
|
|
24
|
+
* broken executable, so it gets its own type instead of looking like a failed spawn.
|
|
25
|
+
*/
|
|
26
|
+
export declare class CommandOutputLimitError extends Error {
|
|
27
|
+
readonly command: string;
|
|
28
|
+
readonly maxOutputBytes: number;
|
|
29
|
+
constructor(command: string, maxOutputBytes: number, options?: ErrorOptions);
|
|
30
|
+
}
|
|
31
|
+
export declare const runCommand: CommandRunner;
|
|
32
|
+
export declare function runChecked(runner: CommandRunner, command: string, args: readonly string[], options: RunCommandOptions, failureContext: string): Promise<CommandResult>;
|
|
33
|
+
//# sourceMappingURL=process.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../src/process.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C;AAED,MAAM,MAAM,aAAa,GAAG,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,iBAAiB,KACvB,OAAO,CAAC,aAAa,CAAC,CAAC;AAY5B,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAElC,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,EAK7F;CACF;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,YAAY,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAO1E;CACF;AAED,eAAO,MAAM,UAAU,EAAE,aAmDxB,CAAC;AAEF,wBAAsB,UAAU,CAC9B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,iBAAiB,EAC1B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,aAAa,CAAC,CAOxB"}
|