@pipelex/sdk 0.24.0 → 0.25.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/dist/client.d.ts +1 -11
- package/dist/client.js +0 -12
- package/dist/client.js.map +1 -1
- package/dist/hooks/check-core.d.ts +97 -8
- package/dist/hooks/check-core.js +164 -15
- package/dist/hooks/check-core.js.map +1 -1
- package/dist/hooks/claude-mthds-check.d.ts +9 -1
- package/dist/hooks/claude-mthds-check.js +48 -31
- package/dist/hooks/claude-mthds-check.js.map +1 -1
- package/dist/hooks/patch-envelope.d.ts +66 -0
- package/dist/hooks/patch-envelope.js +127 -0
- package/dist/hooks/patch-envelope.js.map +1 -0
- package/dist/hooks/shell-script.d.ts +92 -0
- package/dist/hooks/shell-script.js +1304 -0
- package/dist/hooks/shell-script.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/product-models.d.ts +1 -9
- package/dist/product-models.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/architecture.md +1 -2
- package/docs/hook-bundle.md +88 -0
- package/package.json +1 -1
|
@@ -16,9 +16,17 @@
|
|
|
16
16
|
* files — outcomes are merged, any block wins); Vibe reads the stable
|
|
17
17
|
* `post_tool` payload (`tool_status` gate, path resolved against `cwd`).
|
|
18
18
|
*
|
|
19
|
+
* A Codex patch run through the shell (`tool_name: "Bash"`) is placed by
|
|
20
|
+
* following the script's working directory. A file it names by a relative
|
|
21
|
+
* path, or by an absolute one no patch command reads, is checked only when it
|
|
22
|
+
* carries the patch's added lines, and one named by another absolute path
|
|
23
|
+
* only when it does not lack them. The relative paths it could not check are
|
|
24
|
+
* named in one non-blocking note, which a block from another file outranks
|
|
25
|
+
* (see docs/hook-bundle.md).
|
|
26
|
+
*
|
|
19
27
|
* Failure posture (fail-open, per the networked-hook plan):
|
|
20
28
|
* - no `.mthds` in the payload / unparseable stdin → pass silently
|
|
21
|
-
* - WASM engine fails to load →
|
|
29
|
+
* - WASM engine fails to load → no file is checked; the note above is still sent
|
|
22
30
|
* - validate unavailable (no `PIPELEX_API_KEY`, network error, timeout, any
|
|
23
31
|
* non-2xx, bundle-gather overflow) → the local lint/format verdicts already
|
|
24
32
|
* applied; the validate stage passes silently
|
|
@@ -26,9 +34,9 @@
|
|
|
26
34
|
* The hook always exits 0; a block/deny is expressed on stdout, never via the
|
|
27
35
|
* exit code.
|
|
28
36
|
*/
|
|
29
|
-
import {
|
|
37
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
30
38
|
import { resolve as resolvePath } from "node:path";
|
|
31
|
-
import { decideAfterLint, decideAfterValidate, encodeOutcome,
|
|
39
|
+
import { decideAfterLint, decideAfterValidate, encodeOutcome, extractCodexMthdsTargets, extractMthdsFilePath, extractVibeMthdsFilePath, mergeOutcomes, selectCodexTargets, uncheckedShellPatchNote, } from "./check-core.js";
|
|
32
40
|
import { gatherBundle } from "./bundle-gather.js";
|
|
33
41
|
import { createHookClient } from "./validate-client.js";
|
|
34
42
|
/** Per-request ceiling on the one network call — well under the hook's overall timeout. */
|
|
@@ -51,7 +59,19 @@ function parsePlatform(argv) {
|
|
|
51
59
|
}
|
|
52
60
|
return "claude";
|
|
53
61
|
}
|
|
54
|
-
/**
|
|
62
|
+
/** A file's content, or null when there is no file to read. */
|
|
63
|
+
function readFileOrNull(filePath) {
|
|
64
|
+
try {
|
|
65
|
+
return readFileSync(filePath, "utf-8");
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The edited `.mthds` files to check, per platform, and the relative paths of
|
|
73
|
+
* a Codex shell patch the hook could not check.
|
|
74
|
+
*/
|
|
55
75
|
function resolveTargets(platform, stdinJson) {
|
|
56
76
|
let candidates;
|
|
57
77
|
switch (platform) {
|
|
@@ -60,10 +80,8 @@ function resolveTargets(platform, stdinJson) {
|
|
|
60
80
|
candidates = filePath ? [filePath] : [];
|
|
61
81
|
break;
|
|
62
82
|
}
|
|
63
|
-
case "codex":
|
|
64
|
-
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
83
|
+
case "codex":
|
|
84
|
+
return selectCodexTargets(extractCodexMthdsTargets(stdinJson, process.cwd()), readFileOrNull);
|
|
67
85
|
case "vibe": {
|
|
68
86
|
const extracted = extractVibeMthdsFilePath(stdinJson);
|
|
69
87
|
candidates = extracted
|
|
@@ -72,9 +90,7 @@ function resolveTargets(platform, stdinJson) {
|
|
|
72
90
|
break;
|
|
73
91
|
}
|
|
74
92
|
}
|
|
75
|
-
|
|
76
|
-
// paths that may not survive the patch; Claude edits can race a delete).
|
|
77
|
-
return candidates.filter((filePath) => existsSync(filePath));
|
|
93
|
+
return { targets: candidates, unchecked: [] };
|
|
78
94
|
}
|
|
79
95
|
/**
|
|
80
96
|
* Load the WASM engine. The one-line "deprecated parameters" warning the
|
|
@@ -154,14 +170,16 @@ function emit(outcome, platform) {
|
|
|
154
170
|
function warn(message) {
|
|
155
171
|
writeFileSync(2, `[mthds-hook] ${message}\n`);
|
|
156
172
|
}
|
|
157
|
-
/**
|
|
173
|
+
/**
|
|
174
|
+
* The full pipeline on one edited file: lint → format write-back → validate.
|
|
175
|
+
* The file is read here, when its turn comes, and no await separates the read
|
|
176
|
+
* from the write-back, so an edit made while an earlier file was validated is
|
|
177
|
+
* never overwritten with older content.
|
|
178
|
+
*/
|
|
158
179
|
async function checkOneFile(engine, filePath) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
catch {
|
|
164
|
-
return { kind: "pass" }; // file gone since the existence check — nothing to gate
|
|
180
|
+
const content = readFileOrNull(filePath);
|
|
181
|
+
if (content === null) {
|
|
182
|
+
return { kind: "pass" }; // a deleted file has nothing to check (an edit can race a delete)
|
|
165
183
|
}
|
|
166
184
|
// Stage 1 — local lint
|
|
167
185
|
const lintStage = {
|
|
@@ -188,20 +206,19 @@ async function checkOneFile(engine, filePath) {
|
|
|
188
206
|
}
|
|
189
207
|
async function main() {
|
|
190
208
|
const platform = parsePlatform(process.argv.slice(2));
|
|
191
|
-
const
|
|
192
|
-
if (filePaths.length === 0) {
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
let engine;
|
|
196
|
-
try {
|
|
197
|
-
engine = await loadEngine();
|
|
198
|
-
}
|
|
199
|
-
catch {
|
|
200
|
-
return; // engine unavailable — whole hook fails open
|
|
201
|
-
}
|
|
209
|
+
const { targets, unchecked } = resolveTargets(platform, await readStdin());
|
|
202
210
|
const outcomes = [];
|
|
203
|
-
|
|
204
|
-
|
|
211
|
+
if (targets.length > 0) {
|
|
212
|
+
// An engine that cannot load fails the checks open, and only them: the note needs none.
|
|
213
|
+
const engine = await loadEngine().catch(() => null);
|
|
214
|
+
if (engine) {
|
|
215
|
+
for (const target of targets) {
|
|
216
|
+
outcomes.push(await checkOneFile(engine, target));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (unchecked.length > 0) {
|
|
221
|
+
outcomes.push(uncheckedShellPatchNote(unchecked));
|
|
205
222
|
}
|
|
206
223
|
emit(mergeOutcomes(outcomes), platform);
|
|
207
224
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-mthds-check.js","sourceRoot":"","sources":["../../src/hooks/claude-mthds-check.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"claude-mthds-check.js","sourceRoot":"","sources":["../../src/hooks/claude-mthds-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reader of Codex's `apply_patch` envelope, as sections rather than bare
|
|
3
|
+
* header lines.
|
|
4
|
+
*
|
|
5
|
+
* A patch is `*** Begin Patch`, then one section per file, then `*** End
|
|
6
|
+
* Patch`. A section opens with `*** Add File: <path>`, `*** Update File:
|
|
7
|
+
* <path>` (optionally followed by `*** Move to: <path>`) or `*** Delete File:
|
|
8
|
+
* <path>`, and holds the lines under it until the next header. Its `+` lines
|
|
9
|
+
* are the lines the patch adds, which Codex writes to the file verbatim.
|
|
10
|
+
*
|
|
11
|
+
* The text read may be the patch alone (the `apply_patch` tool) or a whole
|
|
12
|
+
* shell script with the patch inside it (Codex's `Bash` tool), so the reader
|
|
13
|
+
* keeps each section's offset for the caller to place it in the script.
|
|
14
|
+
*/
|
|
15
|
+
/** One file's section of a patch. */
|
|
16
|
+
export interface PatchSection {
|
|
17
|
+
kind: "add" | "update" | "delete";
|
|
18
|
+
/** The path as the header wrote it, trimmed. */
|
|
19
|
+
path: string;
|
|
20
|
+
/** The destination of an `Update File` section's `Move to`, or null. */
|
|
21
|
+
moveTo: string | null;
|
|
22
|
+
/** Offset of the section's header line in the text read. */
|
|
23
|
+
offset: number;
|
|
24
|
+
/**
|
|
25
|
+
* How many `*** Begin Patch` and `*** End Patch` lines precede the section:
|
|
26
|
+
* the sections of one envelope share it, and no others do, since an envelope
|
|
27
|
+
* ends on its `End Patch` line even when its `Begin Patch` does not start a
|
|
28
|
+
* line, as in `apply_patch '*** Begin Patch`.
|
|
29
|
+
*/
|
|
30
|
+
envelope: number;
|
|
31
|
+
/** The section's `+` lines, marker stripped, otherwise as written. */
|
|
32
|
+
addedLines: string[];
|
|
33
|
+
}
|
|
34
|
+
/** A file the patch leaves on disk. */
|
|
35
|
+
export interface SurvivingFile {
|
|
36
|
+
/** The caller's key for the file. */
|
|
37
|
+
key: string;
|
|
38
|
+
/** The path as the first section leaving the file named it: its own, or its `Move to`. */
|
|
39
|
+
path: string;
|
|
40
|
+
/** Each envelope's last section that leaves the file on disk. */
|
|
41
|
+
sections: PatchSection[];
|
|
42
|
+
/** Some section deletes the file or moves it away, so its absence may be the patch's doing. */
|
|
43
|
+
removedByPatch: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Every section of every patch envelope in `text`, in order. The recognised
|
|
47
|
+
* headers are anchored at the start of a line, as the `pipelex-plugins`
|
|
48
|
+
* wrapper's pre-filter reads them; a `Move to` counts only inside an `Update
|
|
49
|
+
* File` section, and a `Begin Patch` or `End Patch` line closes the section
|
|
50
|
+
* before it and starts a new envelope, so script lines after a patch are not
|
|
51
|
+
* read as its content, and the patches of a script stay apart.
|
|
52
|
+
*/
|
|
53
|
+
export declare function readPatchSections(text: string): PatchSection[];
|
|
54
|
+
/**
|
|
55
|
+
* The `.mthds` files that survive the sections. Within one envelope the
|
|
56
|
+
* sections apply in order and in one directory: an added or updated file
|
|
57
|
+
* becomes a target, a moved file stops being one and its destination becomes
|
|
58
|
+
* one, and a deleted file stops being one. The envelopes of a shell script
|
|
59
|
+
* may run in other directories, in branches, or not at all, so across them a
|
|
60
|
+
* file survives when any envelope leaves it, and a delete in one never hides
|
|
61
|
+
* another's edit. Two paths name the same file when `keyOf` gives them the
|
|
62
|
+
* same key, which lets the caller compare paths resolved against the
|
|
63
|
+
* directory each section was applied in; by default the paths are compared
|
|
64
|
+
* as written.
|
|
65
|
+
*/
|
|
66
|
+
export declare function patchTargets(sections: readonly PatchSection[], keyOf?: (path: string, section: PatchSection) => string): SurvivingFile[];
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reader of Codex's `apply_patch` envelope, as sections rather than bare
|
|
3
|
+
* header lines.
|
|
4
|
+
*
|
|
5
|
+
* A patch is `*** Begin Patch`, then one section per file, then `*** End
|
|
6
|
+
* Patch`. A section opens with `*** Add File: <path>`, `*** Update File:
|
|
7
|
+
* <path>` (optionally followed by `*** Move to: <path>`) or `*** Delete File:
|
|
8
|
+
* <path>`, and holds the lines under it until the next header. Its `+` lines
|
|
9
|
+
* are the lines the patch adds, which Codex writes to the file verbatim.
|
|
10
|
+
*
|
|
11
|
+
* The text read may be the patch alone (the `apply_patch` tool) or a whole
|
|
12
|
+
* shell script with the patch inside it (Codex's `Bash` tool), so the reader
|
|
13
|
+
* keeps each section's offset for the caller to place it in the script.
|
|
14
|
+
*/
|
|
15
|
+
const SECTION_HEADER = /^\*\*\* (Add File|Update File|Delete File):\s*(.*?)\s*$/;
|
|
16
|
+
const MOVE_HEADER = /^\*\*\* Move to:\s*(.*?)\s*$/;
|
|
17
|
+
const ENVELOPE_BOUNDARY = /^\*\*\* (Begin|End) Patch\b/;
|
|
18
|
+
const MTHDS_PATH = /.\.mthds$/;
|
|
19
|
+
const SECTION_KINDS = {
|
|
20
|
+
"Add File": "add",
|
|
21
|
+
"Update File": "update",
|
|
22
|
+
"Delete File": "delete",
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Every section of every patch envelope in `text`, in order. The recognised
|
|
26
|
+
* headers are anchored at the start of a line, as the `pipelex-plugins`
|
|
27
|
+
* wrapper's pre-filter reads them; a `Move to` counts only inside an `Update
|
|
28
|
+
* File` section, and a `Begin Patch` or `End Patch` line closes the section
|
|
29
|
+
* before it and starts a new envelope, so script lines after a patch are not
|
|
30
|
+
* read as its content, and the patches of a script stay apart.
|
|
31
|
+
*/
|
|
32
|
+
export function readPatchSections(text) {
|
|
33
|
+
const sections = [];
|
|
34
|
+
let current = null;
|
|
35
|
+
let envelope = 0;
|
|
36
|
+
let lineStart = 0;
|
|
37
|
+
while (lineStart <= text.length) {
|
|
38
|
+
const newline = text.indexOf("\n", lineStart);
|
|
39
|
+
const lineEnd = newline === -1 ? text.length : newline;
|
|
40
|
+
const line = text.slice(lineStart, lineEnd).replace(/\r$/, "");
|
|
41
|
+
const header = SECTION_HEADER.exec(line);
|
|
42
|
+
const boundary = ENVELOPE_BOUNDARY.exec(line);
|
|
43
|
+
if (header) {
|
|
44
|
+
current = null;
|
|
45
|
+
if (header[2]) {
|
|
46
|
+
current = {
|
|
47
|
+
kind: SECTION_KINDS[header[1]],
|
|
48
|
+
path: header[2],
|
|
49
|
+
moveTo: null,
|
|
50
|
+
offset: lineStart,
|
|
51
|
+
envelope,
|
|
52
|
+
addedLines: [],
|
|
53
|
+
};
|
|
54
|
+
sections.push(current);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (boundary) {
|
|
58
|
+
current = null;
|
|
59
|
+
envelope++;
|
|
60
|
+
}
|
|
61
|
+
else if (current) {
|
|
62
|
+
const move = MOVE_HEADER.exec(line);
|
|
63
|
+
if (move) {
|
|
64
|
+
if (current.kind === "update" && current.moveTo === null && move[1]) {
|
|
65
|
+
current.moveTo = move[1];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (line.startsWith("+")) {
|
|
69
|
+
current.addedLines.push(line.slice(1));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (newline === -1) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
lineStart = newline + 1;
|
|
76
|
+
}
|
|
77
|
+
return sections;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The `.mthds` files that survive the sections. Within one envelope the
|
|
81
|
+
* sections apply in order and in one directory: an added or updated file
|
|
82
|
+
* becomes a target, a moved file stops being one and its destination becomes
|
|
83
|
+
* one, and a deleted file stops being one. The envelopes of a shell script
|
|
84
|
+
* may run in other directories, in branches, or not at all, so across them a
|
|
85
|
+
* file survives when any envelope leaves it, and a delete in one never hides
|
|
86
|
+
* another's edit. Two paths name the same file when `keyOf` gives them the
|
|
87
|
+
* same key, which lets the caller compare paths resolved against the
|
|
88
|
+
* directory each section was applied in; by default the paths are compared
|
|
89
|
+
* as written.
|
|
90
|
+
*/
|
|
91
|
+
export function patchTargets(sections, keyOf = (path) => path) {
|
|
92
|
+
const envelopes = new Map();
|
|
93
|
+
for (const section of sections) {
|
|
94
|
+
envelopes.set(section.envelope, [...(envelopes.get(section.envelope) ?? []), section]);
|
|
95
|
+
}
|
|
96
|
+
const files = new Map();
|
|
97
|
+
const removed = new Set();
|
|
98
|
+
for (const envelope of envelopes.values()) {
|
|
99
|
+
const surviving = new Map();
|
|
100
|
+
for (const section of envelope) {
|
|
101
|
+
const key = keyOf(section.path, section);
|
|
102
|
+
if (section.kind === "delete" || section.moveTo !== null) {
|
|
103
|
+
surviving.delete(key);
|
|
104
|
+
removed.add(key);
|
|
105
|
+
}
|
|
106
|
+
if (section.moveTo !== null) {
|
|
107
|
+
surviving.set(keyOf(section.moveTo, section), { path: section.moveTo, section });
|
|
108
|
+
}
|
|
109
|
+
else if (section.kind !== "delete") {
|
|
110
|
+
surviving.set(key, { path: section.path, section });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
for (const [key, { path, section }] of surviving) {
|
|
114
|
+
const file = files.get(key);
|
|
115
|
+
if (file) {
|
|
116
|
+
file.sections.push(section);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
files.set(key, { key, path, sections: [section], removedByPatch: false });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return Array.from(files.values())
|
|
124
|
+
.filter((file) => MTHDS_PATH.test(file.path))
|
|
125
|
+
.map((file) => ({ ...file, removedByPatch: removed.has(file.key) }));
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=patch-envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-envelope.js","sourceRoot":"","sources":["../../src/hooks/patch-envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A reading of a POSIX shell script that tells, for an offset in it, which
|
|
3
|
+
* directory the patch command reading that offset runs in.
|
|
4
|
+
*
|
|
5
|
+
* Codex reports a patch run through the shell as a `Bash` call carrying the
|
|
6
|
+
* whole script, and a relative path in that patch is relative to wherever the
|
|
7
|
+
* script had moved when `apply_patch` ran. This module lexes the script far
|
|
8
|
+
* enough to follow `cd`: commands, quotes, heredocs, substitutions, scopes,
|
|
9
|
+
* branches and loops. It is not a shell parser. Past what it reads, it
|
|
10
|
+
* answers "unknown" rather than guessing, and a script it cannot lex at all
|
|
11
|
+
* is "unparsed".
|
|
12
|
+
*
|
|
13
|
+
* - Text is placed only where a patch command reads it: the words and
|
|
14
|
+
* heredoc bodies of an `apply_patch` command, and the text of a command
|
|
15
|
+
* feeding one through a pipeline or a substitution in its words. Text that
|
|
16
|
+
* any other command holds, such as a variable, a file, `bash -c` or `eval`,
|
|
17
|
+
* is unknown, since this reading does not follow whatever reads it later.
|
|
18
|
+
* - `cd DIR` with one literal operand (optionally after `-L`, `-P` or `--`)
|
|
19
|
+
* moves the directory, and is assumed to succeed; any other `cd`, and
|
|
20
|
+
* `pushd`, `popd`, `eval`, `source`, `.` or a function definition, makes
|
|
21
|
+
* it unknown. An absolute `cd` makes an unknown directory known again.
|
|
22
|
+
* - The reading follows the path on which each command succeeds, so a
|
|
23
|
+
* negated `cd` fails on it. What runs only on the other path (after `||`,
|
|
24
|
+
* in `elif` and `else`, after a negated `cd` and `&&`, and on the path a
|
|
25
|
+
* loop's condition takes to end or skip it) starts where the shell stood
|
|
26
|
+
* when nothing had moved it, and from an unknown directory otherwise.
|
|
27
|
+
* - `( … )`, `$( … )`, `<( … )` and `>( … )` are scopes: a `cd` inside one
|
|
28
|
+
* ends at its closing parenthesis. A list sent to the background, and every
|
|
29
|
+
* member of a pipeline but the last, run in subshells in bash and zsh
|
|
30
|
+
* alike. zsh runs a pipeline's last member in the current shell and bash
|
|
31
|
+
* does not, so a directory change there makes the directory after it
|
|
32
|
+
* unknown.
|
|
33
|
+
* - `{ … }` and the separators `;`, newline and `&&` are followed in order.
|
|
34
|
+
* Where only one of several paths runs, after `||`, between the branches of
|
|
35
|
+
* `if` and `case`, and across the passes of a loop, the directory is kept
|
|
36
|
+
* when every path leaves it the same, and is unknown otherwise.
|
|
37
|
+
* - Heredoc bodies, quoted strings, comments and the expression of a `[[ … ]]`
|
|
38
|
+
* are never read as commands. A heredoc body belongs to the command that
|
|
39
|
+
* opened it.
|
|
40
|
+
* - The text a command reads is the script's after the shell's quoting, which
|
|
41
|
+
* the reading also tells: a patch in double quotes or in an unquoted heredoc
|
|
42
|
+
* has its backslash escapes removed and its `$` and backtick expansions run.
|
|
43
|
+
*/
|
|
44
|
+
/** Where the patch command reading an offset runs. */
|
|
45
|
+
export type Placement = {
|
|
46
|
+
kind: "directory";
|
|
47
|
+
path: string;
|
|
48
|
+
}
|
|
49
|
+
/** A patch command reads the offset from somewhere this reading cannot follow. */
|
|
50
|
+
| {
|
|
51
|
+
kind: "unknown";
|
|
52
|
+
}
|
|
53
|
+
/** A command holds the offset, and no patch command reads it: a variable, a file, `bash -c`. */
|
|
54
|
+
| {
|
|
55
|
+
kind: "unread";
|
|
56
|
+
}
|
|
57
|
+
/** No command holds the offset: it is in a comment or between commands. */
|
|
58
|
+
| {
|
|
59
|
+
kind: "outside";
|
|
60
|
+
};
|
|
61
|
+
/** How the shell turns a stretch of the script into the text a command reads. */
|
|
62
|
+
export type Quoting =
|
|
63
|
+
/** As written: in a quoted heredoc, or plain. */
|
|
64
|
+
"verbatim"
|
|
65
|
+
/** In single quotes: as written, up to the `'` that closes them. */
|
|
66
|
+
| "single-quoted"
|
|
67
|
+
/** In double quotes: a backslash escapes `$`, a backtick, `"` or itself, and `$` and backticks expand. */
|
|
68
|
+
| "double-quoted"
|
|
69
|
+
/** In an unquoted heredoc: a backslash escapes `$`, a backtick or itself, and `$` and backticks expand. */
|
|
70
|
+
| "heredoc";
|
|
71
|
+
/** A script that could be lexed, able to place any offset in it. */
|
|
72
|
+
export interface ShellReading {
|
|
73
|
+
directoryAt(offset: number): Placement;
|
|
74
|
+
quotingAt(offset: number): Quoting;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Read `script` as a POSIX shell script run from `sessionDir`, or return
|
|
78
|
+
* `"unparsed"` when it holds an unterminated quote, substitution or backtick,
|
|
79
|
+
* a heredoc inside backticks, a parenthesis that closes nothing, or any other
|
|
80
|
+
* syntax error this reading can see.
|
|
81
|
+
*/
|
|
82
|
+
export declare function readShellScript(script: string, sessionDir: string): ShellReading | "unparsed";
|
|
83
|
+
/**
|
|
84
|
+
* The lines of a patch section as the patch command reads them, given the
|
|
85
|
+
* quoting its header is in, less any line an expansion makes unknown. A line
|
|
86
|
+
* in quotes may close them and open others, as `'\''` writes an apostrophe in
|
|
87
|
+
* single quotes, and is read through each. When a line ends in other quoting
|
|
88
|
+
* than it began in, or in a backslash that joins it to the next, the lines
|
|
89
|
+
* after it are read in quoting this reading does not follow, so no line of
|
|
90
|
+
* the section is known and none is given.
|
|
91
|
+
*/
|
|
92
|
+
export declare function linesAsRead(lines: readonly string[], quoting: Quoting): string[];
|