@pipelex/sdk 0.23.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.
Files changed (43) hide show
  1. package/dist/artifacts.d.ts +4 -1
  2. package/dist/artifacts.js +6 -1
  3. package/dist/artifacts.js.map +1 -1
  4. package/dist/client.d.ts +7 -13
  5. package/dist/client.js +15 -16
  6. package/dist/client.js.map +1 -1
  7. package/dist/errors.d.ts +30 -5
  8. package/dist/errors.js +9 -5
  9. package/dist/errors.js.map +1 -1
  10. package/dist/hooks/check-core.d.ts +97 -8
  11. package/dist/hooks/check-core.js +164 -15
  12. package/dist/hooks/check-core.js.map +1 -1
  13. package/dist/hooks/claude-mthds-check.d.ts +9 -1
  14. package/dist/hooks/claude-mthds-check.js +48 -31
  15. package/dist/hooks/claude-mthds-check.js.map +1 -1
  16. package/dist/hooks/patch-envelope.d.ts +66 -0
  17. package/dist/hooks/patch-envelope.js +127 -0
  18. package/dist/hooks/patch-envelope.js.map +1 -0
  19. package/dist/hooks/shell-script.d.ts +92 -0
  20. package/dist/hooks/shell-script.js +1304 -0
  21. package/dist/hooks/shell-script.js.map +1 -0
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/product-models.d.ts +1 -9
  25. package/dist/product-models.js +1 -1
  26. package/dist/runs.d.ts +10 -1
  27. package/dist/runs.js +17 -1
  28. package/dist/runs.js.map +1 -1
  29. package/dist/timers.d.ts +11 -0
  30. package/dist/timers.js +14 -0
  31. package/dist/timers.js.map +1 -0
  32. package/dist/upload-grant.d.ts +38 -15
  33. package/dist/upload-grant.js +200 -67
  34. package/dist/upload-grant.js.map +1 -1
  35. package/dist/upload.js +9 -2
  36. package/dist/upload.js.map +1 -1
  37. package/dist/version.d.ts +1 -1
  38. package/dist/version.js +1 -1
  39. package/docs/architecture.md +4 -4
  40. package/docs/artifact-download.md +1 -1
  41. package/docs/hook-bundle.md +88 -0
  42. package/docs/input-preparation.md +14 -8
  43. package/package.json +2 -2
@@ -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[];