@pipelex/sdk 0.46.1 → 0.48.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 (51) hide show
  1. package/README.md +20 -9
  2. package/dist/cli/script.d.ts +1 -1
  3. package/dist/cli/source.d.ts +8 -7
  4. package/dist/cli/source.js +11 -5
  5. package/dist/cli/source.js.map +1 -1
  6. package/dist/client.d.ts +455 -237
  7. package/dist/client.js +1067 -522
  8. package/dist/client.js.map +1 -1
  9. package/dist/errors.d.ts +49 -19
  10. package/dist/errors.js +50 -21
  11. package/dist/errors.js.map +1 -1
  12. package/dist/hooks/bundle-gather.d.ts +28 -40
  13. package/dist/hooks/bundle-gather.js +55 -230
  14. package/dist/hooks/bundle-gather.js.map +1 -1
  15. package/dist/hooks/claude-mthds-check.d.ts +7 -5
  16. package/dist/hooks/claude-mthds-check.js +8 -53
  17. package/dist/hooks/claude-mthds-check.js.map +1 -1
  18. package/dist/hooks/validate-stage.d.ts +27 -0
  19. package/dist/hooks/validate-stage.js +57 -0
  20. package/dist/hooks/validate-stage.js.map +1 -0
  21. package/dist/index.d.ts +7 -7
  22. package/dist/index.js +6 -3
  23. package/dist/index.js.map +1 -1
  24. package/dist/method-trees.d.ts +344 -0
  25. package/dist/method-trees.js +876 -0
  26. package/dist/method-trees.js.map +1 -0
  27. package/dist/models.d.ts +162 -59
  28. package/dist/prepare-inputs.d.ts +46 -27
  29. package/dist/prepare-inputs.js +123 -42
  30. package/dist/prepare-inputs.js.map +1 -1
  31. package/dist/product-models.d.ts +97 -75
  32. package/dist/runs.d.ts +5 -3
  33. package/dist/runs.js.map +1 -1
  34. package/dist/version.d.ts +1 -1
  35. package/dist/version.js +1 -1
  36. package/docs/architecture.md +20 -21
  37. package/docs/cli.md +1 -1
  38. package/docs/crate-routes.md +42 -20
  39. package/docs/errors.md +7 -6
  40. package/docs/hook-bundle.md +1 -1
  41. package/docs/input-preparation.md +15 -40
  42. package/docs/method-trees.md +199 -0
  43. package/docs/run-results.md +5 -2
  44. package/package.json +2 -2
  45. package/dist/bundle-resources.d.ts +0 -62
  46. package/dist/bundle-resources.js +0 -165
  47. package/dist/bundle-resources.js.map +0 -1
  48. package/dist/method-source.d.ts +0 -19
  49. package/dist/method-source.js +0 -50
  50. package/dist/method-source.js.map +0 -1
  51. package/docs/bundle-resources.md +0 -107
@@ -1,165 +0,0 @@
1
- /**
2
- * The files a bundle's steps read, sent with the bundle as the request's `resources`.
3
- *
4
- * A bundle sent as content has no directory, so a file one of its steps reads from beside the
5
- * bundle, such as a `PipeDocGen` step's `template_file`, has to travel with it. The runner takes
6
- * such files as `resources`: a JSON object mapping each file's path, exactly as the step names it,
7
- * relative to the bundle and written with forward slashes, to the file's bytes in standard padded
8
- * base64. It takes them beside `mthds_contents` (or a method bundle) on `/v1/validate`,
9
- * `/v1/execute` and `/v1/start`, and beside inline `files[]` on `/v1/pipe-io`, `/v1/resolve` and
10
- * `/v1/codegen`. A caller hands this SDK the bytes, keyed by that path, and the SDK encodes them.
11
- *
12
- * The SDK refuses before any request what the runner refuses for certain about the keys, with the
13
- * runner's own rule (`resource_path_refusal` in pipelex's `bundle_resource.py`): an empty path, a
14
- * backslash, a colon, a NUL character, an absolute path, a `..` segment, a path naming no file,
15
- * and two keys naming one file once `.` segments and repeated slashes collapse. Each is a
16
- * `RequestArgumentError` naming the key, where the runner answers a `422` `InvalidResourcePath`.
17
- * The sizes are left to the server, since a deployment configures them: 32 files, 5 MiB each and
18
- * 10 MiB in all by default, a `413` `PayloadTooLarge` beyond, and 512 KiB in all for the `.html`
19
- * template files, a `413` `BundleResourcesTooLargeError`. So is every rule that needs the parsed
20
- * bundle: a file no step names is a `422` `BundleResourceNotNamedError`.
21
- */
22
- import { RequestArgumentError } from "./errors.js";
23
- import { bytesToBase64 } from "./upload.js";
24
- /**
25
- * Whether `resources` is a plain object, the one shape a map of paths to bytes takes: its
26
- * prototype is `Object.prototype` or `null`. A `Map`, an array or a class instance is not one,
27
- * and the encoder refuses it rather than reading it as a map with no file in it.
28
- */
29
- export function isResourceMap(resources) {
30
- if (typeof resources !== "object" || resources === null)
31
- return false;
32
- const prototype = Object.getPrototypeOf(resources);
33
- return prototype === Object.prototype || prototype === null;
34
- }
35
- /**
36
- * Whether `resources` carries at least one file. An absent, `null` or empty map carries none, so
37
- * it is not sent, as an empty bundle encoding is not. A value that is not a plain object carries
38
- * none either; the encoder refuses it.
39
- */
40
- export function hasBundleResources(resources) {
41
- return isResourceMap(resources) && Object.keys(resources).length > 0;
42
- }
43
- /**
44
- * Python's whitespace, the set `str.strip()` removes and `str.isspace()` accepts, which the
45
- * runner's rule tests a path against. It differs from JavaScript's `trim()`: it holds the
46
- * separators U+001C to U+001F and U+0085, and not the byte-order mark U+FEFF.
47
- */
48
- const PYTHON_WHITESPACE = new Set([
49
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x85, 0xa0, 0x1680, 0x2000, 0x2001,
50
- 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x2028, 0x2029, 0x202f,
51
- 0x205f, 0x3000,
52
- ]);
53
- /** Whether `path` holds nothing but Python's whitespace: `not path.strip()`, the runner's test. */
54
- function isBlankForPython(path) {
55
- for (const character of path) {
56
- if (!PYTHON_WHITESPACE.has(character.codePointAt(0)))
57
- return false;
58
- }
59
- return true;
60
- }
61
- /**
62
- * Why `path` cannot name a file inside a bundle, or `undefined` when it can — the runner's rule,
63
- * held by the key of a file sent with a bundle and by the path a step names.
64
- */
65
- export function bundleResourcePathRefusal(path) {
66
- if (isBlankForPython(path))
67
- return "it is empty";
68
- if (path.includes("\\"))
69
- return "it holds a backslash; write the path with forward slashes";
70
- if (path.includes(":"))
71
- return "it holds a colon";
72
- if (path.includes("\0"))
73
- return "it holds a NUL character";
74
- if (path.startsWith("/"))
75
- return "it is absolute; write it relative to the bundle";
76
- const segments = pathSegments(path);
77
- if (segments.includes(".."))
78
- return "it leaves the bundle through a '..' segment";
79
- if (segments.length === 0)
80
- return "it names no file";
81
- return undefined;
82
- }
83
- /**
84
- * The one spelling of a bundle-relative path the runner keys a file by: `.` segments and repeated
85
- * slashes collapse, so `./templates//invoice.docx` is `templates/invoice.docx`. Only meaningful
86
- * for a path {@link bundleResourcePathRefusal} accepts.
87
- */
88
- export function canonicalBundleResourcePath(path) {
89
- return pathSegments(path).join("/");
90
- }
91
- function pathSegments(path) {
92
- return path.split("/").filter((segment) => segment !== "" && segment !== ".");
93
- }
94
- /**
95
- * Encode `resources` for the wire: each key as given, each value as its bytes in standard padded
96
- * base64. Returns `undefined` when there is nothing to send, so the key stays off the wire.
97
- *
98
- * Every key is checked before any value is read, so a refused path costs no read of a `Blob`.
99
- *
100
- * @throws {RequestArgumentError} `resources` is not a map of paths to bytes, a key cannot name a
101
- * file inside the bundle, two keys name one file, or a value is not bytes.
102
- */
103
- export async function encodeBundleResources(resources) {
104
- if (resources === undefined || resources === null)
105
- return undefined;
106
- if (!isResourceMap(resources)) {
107
- throw new RequestArgumentError("resources must be a plain object mapping each file's path, as the step names it, to the " +
108
- `file's bytes; got ${describeValue(resources)}.`);
109
- }
110
- // Read once: a second read of a proxy or a getter could differ from the one checked.
111
- const entries = Object.entries(resources);
112
- if (entries.length === 0)
113
- return undefined;
114
- const pathByCanonical = new Map();
115
- for (const [path] of entries) {
116
- const refusal = bundleResourcePathRefusal(path);
117
- if (refusal !== undefined) {
118
- throw new RequestArgumentError(`resources key ${JSON.stringify(path)} cannot name a file inside the bundle: ${refusal}.`);
119
- }
120
- const canonical = canonicalBundleResourcePath(path);
121
- const first = pathByCanonical.get(canonical);
122
- if (first !== undefined) {
123
- throw new RequestArgumentError(`resources keys ${JSON.stringify(first)} and ${JSON.stringify(path)} name the same file ` +
124
- `"${canonical}": send it once.`);
125
- }
126
- pathByCanonical.set(canonical, path);
127
- }
128
- // A null prototype, so a key such as `__proto__` is an own property that reaches the wire.
129
- const wire = Object.create(null);
130
- for (const [path, value] of entries) {
131
- wire[path] = bytesToBase64(await resourceBytes(path, value));
132
- }
133
- return wire;
134
- }
135
- async function resourceBytes(path, value) {
136
- if (value instanceof Uint8Array)
137
- return value;
138
- if (value instanceof ArrayBuffer)
139
- return new Uint8Array(value);
140
- if (typeof Blob !== "undefined" && value instanceof Blob) {
141
- return new Uint8Array(await value.arrayBuffer());
142
- }
143
- throw new RequestArgumentError(`resources[${JSON.stringify(path)}] must be the file's bytes (a Uint8Array, an ArrayBuffer ` +
144
- `or a Blob); got ${describeValue(value)}.` +
145
- (typeof value === "string"
146
- ? " A string is read neither as a path nor as base64: read the file and pass its bytes."
147
- : ""));
148
- }
149
- function describeValue(value) {
150
- if (value === null)
151
- return "null";
152
- if (Array.isArray(value))
153
- return "an array";
154
- if (value instanceof Map)
155
- return "a Map; pass Object.fromEntries(map)";
156
- if (typeof value === "string")
157
- return "a string";
158
- if (typeof value === "object") {
159
- const name = Object.getPrototypeOf(value)
160
- ?.constructor?.name;
161
- return typeof name === "string" && name !== "" ? `an instance of ${name}` : "an object";
162
- }
163
- return `a value of type ${typeof value}`;
164
- }
165
- //# sourceMappingURL=bundle-resources.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bundle-resources.js","sourceRoot":"","sources":["../src/bundle-resources.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- /**
2
- * Parse a stored method's polymorphic `MethodData.mthds` source into bundle
3
- * file contents. The string is either raw `.mthds` source or a JSON-serialized
4
- * `[{ name, content }, …]` file array (the webapp editor format).
5
- *
6
- * Mirrors the platform's canonical implementation — `method_source_to_contents`
7
- * plus its caller's blank-source guard in `resolve_method_run_source`, both in
8
- * the platform's `services/method_resolution.py` — keep the two in sync. A JSON
9
- * `[]` is "no source", not a bundle; a JSON array of `{ name, content }`
10
- * objects yields the non-blank contents; anything else (raw source, non-array
11
- * JSON, unparseable) is one plain bundle string, itself dropped when blank.
12
- * An empty result means the stored method has no MTHDS source.
13
- *
14
- * One deliberate divergence: the platform's blank-source guard is a falsy
15
- * check (`if method.mthds`), so a whitespace-only raw source would pass there
16
- * and fail downstream at parse; here it trims to "no source" — a clearer
17
- * verdict for the same degenerate input.
18
- */
19
- export declare function methodSourceToContents(mthds: string): string[];
@@ -1,50 +0,0 @@
1
- /**
2
- * Parse a stored method's polymorphic `MethodData.mthds` source into bundle
3
- * file contents. The string is either raw `.mthds` source or a JSON-serialized
4
- * `[{ name, content }, …]` file array (the webapp editor format).
5
- *
6
- * Mirrors the platform's canonical implementation — `method_source_to_contents`
7
- * plus its caller's blank-source guard in `resolve_method_run_source`, both in
8
- * the platform's `services/method_resolution.py` — keep the two in sync. A JSON
9
- * `[]` is "no source", not a bundle; a JSON array of `{ name, content }`
10
- * objects yields the non-blank contents; anything else (raw source, non-array
11
- * JSON, unparseable) is one plain bundle string, itself dropped when blank.
12
- * An empty result means the stored method has no MTHDS source.
13
- *
14
- * One deliberate divergence: the platform's blank-source guard is a falsy
15
- * check (`if method.mthds`), so a whitespace-only raw source would pass there
16
- * and fail downstream at parse; here it trims to "no source" — a clearer
17
- * verdict for the same degenerate input.
18
- */
19
- export function methodSourceToContents(mthds) {
20
- // The API types `mthds` as string, but mirror the platform's falsy guard so
21
- // a contract-violating null/undefined reads as "no source", not a crash.
22
- if (!mthds) {
23
- return [];
24
- }
25
- let parsed;
26
- try {
27
- parsed = JSON.parse(mthds);
28
- }
29
- catch {
30
- return rawBundle(mthds);
31
- }
32
- if (Array.isArray(parsed)) {
33
- if (parsed.length === 0) {
34
- return [];
35
- }
36
- if (parsed.every(isFileEntry)) {
37
- return parsed
38
- .map((entry) => entry.content)
39
- .filter((content) => typeof content === "string" && content.trim() !== "");
40
- }
41
- }
42
- return rawBundle(mthds);
43
- }
44
- function rawBundle(mthds) {
45
- return mthds.trim() === "" ? [] : [mthds];
46
- }
47
- function isFileEntry(entry) {
48
- return typeof entry === "object" && entry !== null && "name" in entry && "content" in entry;
49
- }
50
- //# sourceMappingURL=method-source.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"method-source.js","sourceRoot":"","sources":["../src/method-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,4EAA4E;IAC5E,yEAAyE;IACzE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9B,OAAO,MAAM;iBACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;iBAC7B,MAAM,CACL,CAAC,OAAO,EAAqB,EAAE,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CACrF,CAAC;QACN,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,SAAS,IAAI,KAAK,CAAC;AAC9F,CAAC"}
@@ -1,107 +0,0 @@
1
- # The files a bundle's steps read (`resources`)
2
-
3
- A bundle sent to the API as content has no directory, so a file one of its steps reads from beside the bundle has to travel with it. Today that is a `PipeDocGen` step's `template_file`: the Word, Excel or PowerPoint template it fills, or the HTML template it prints as a PDF. The runner takes such files as the request's `resources`, a JSON object mapping each file's path, exactly as the step names it, to the file's bytes in standard padded base64. This SDK takes the bytes from you, keyed by that path, and encodes them.
4
-
5
- ```ts
6
- import { readFile } from "node:fs/promises";
7
-
8
- const mthds = await readFile("invoicing/bundle.mthds", "utf8");
9
- const resources = {
10
- "templates/invoice.docx": await readFile("invoicing/templates/invoice.docx"),
11
- };
12
-
13
- const verdict = await client.validate([mthds], false, ["bundle.mthds"], undefined, undefined, {
14
- resources,
15
- });
16
- const result = await client.startAndWaitForResult({ mthds_contents: [mthds], resources, inputs });
17
- ```
18
-
19
- ## Where they go
20
-
21
- | Call | Where `resources` goes |
22
- | --- | --- |
23
- | `validate(contents, …, options)` | `options.resources`, beside inline contents or a hosted `{ method_id }` |
24
- | `validateFiles(files, options)` | `options.resources` |
25
- | `execute(options)`, `start(options)`, `startAndWaitForResult(options)` | `options.resources`, beside `mthds_contents`, a method bundle (`files` or `bundle_b64`) or a hosted `method_id`; the blocking fallback a bare runner takes sends them too |
26
- | `pipeIo(request)`, `resolve(request)`, `codegen(request)` | `request.resources`, beside inline `files` |
27
- | `prepareInputs(request)` | `request.resources`, beside inline `files`, sent with the one pipe I/O request that reads the signature |
28
-
29
- An absent, `null` or empty map is not sent.
30
-
31
- A request carrying `resources` can be large, so every route gives it the 20-minute execute ceiling: `validate` and `validateFiles` have it by default (a caller's `timeoutMs` still overrides it), and `start` and the crate routes raise their shorter default to it for a request that carries a file. On the hosted API the gateway caps a request at about 30 seconds whatever the client allows.
32
-
33
- ## The key is the path the step names
34
-
35
- Each key is the file's path relative to the bundle, written with forward slashes, exactly as the step's `template_file` writes it: `templates/invoice.docx`. The runner collapses `.` segments and repeated slashes, so `./templates/invoice.docx` names the same file, and the SDK sends the key as you gave it. Every bundle of a request is read as sitting in one directory, so a step in `steps/print.mthds` that names `templates/invoice.docx` reads the file sent under `templates/invoice.docx`, wherever it sat on your disk.
36
-
37
- ## The value is the file's bytes
38
-
39
- A value is a `Uint8Array` (a Node `Buffer` is one), an `ArrayBuffer` or a `Blob`, the byte forms `uploadFile` takes. The SDK sends each in standard base64 with padding. A string is refused: it would have to be a path the SDK reads or base64 it decodes, and it is neither. The SDK reads no file because a request named it, which keeps a server that sends a request on a caller's behalf from reading its own files; read the file yourself and pass its bytes.
40
-
41
- ## What the SDK refuses before any request
42
-
43
- Each of these is a `RequestArgumentError`, `input` and not retryable, thrown before anything is encoded or sent:
44
-
45
- - **A key that cannot name a file inside the bundle**: an empty path or one of nothing but whitespace, as Python counts it, a backslash, a colon, a NUL character, an absolute path, a `..` segment, or a path that names no file (`./`). It is the runner's own rule, which it answers with a `422` `InvalidResourcePath`.
46
- - **Two keys that name one file** once `.` segments and repeated slashes collapse, such as `a.docx` and `./a.docx`.
47
- - **A value that is not bytes**, and a `resources` that is not a plain object mapping paths to bytes: a `Map`, an array or a class instance is refused rather than read as carrying no file (pass `Object.fromEntries(map)`).
48
- - **`resources` in `extra`**: it is a named option, so the passthrough cannot carry it past these checks.
49
- - **A pairing the runner refuses**, on the routes where the SDK already mirrors the runner's pairings. On `execute` and `start`, `resources` beside a `method_ref`, whose files are its package's own, or with no source at all for them to accompany. On `validate`, `resources` beside a `{ method_ref }`. A hosted `method_id` without inline source is left to the server, since the platform resolves it into the bundle the runner reads the files with. `prepareInputs` takes `resources` beside inline `files` only, and refuses them beside a `method_ref` or a `method_id` with an `InputPreparationError`.
50
-
51
- The crate routes post their request as given, apart from encoding `resources`, and leave their pairings to the server, which answers `resources` beside a `method_ref` with a `422` `ValidationError`.
52
-
53
- The sizes are left to the server, since a deployment configures them.
54
-
55
- ## What the server refuses
56
-
57
- Every refusal is an `ApiResponseError`, `input` and not retryable; branch on its `errorType`:
58
-
59
- | Status | `errorType` | When |
60
- | --- | --- | --- |
61
- | `422` | `InvalidResourcePath` | A key that cannot name a file inside the bundle, two keys for one file, or, on a run route, two different files under one path, one sent in `resources` and one shipped in a method bundle. |
62
- | `422` | `BundleResourceNotNamedError` | A file no step of the bundle names, on every route, the diagnostic ones included; its detail lists the unnamed paths. A misspelled key fails here rather than leaving its step without its file. |
63
- | `422` | `ValidationError` | `resources` beside a `method_ref`, or on a run route with no bundle. |
64
- | `413` | `PayloadTooLarge` | More files than the deployment allows (32 by default), a file over its per-file limit (5 MiB by default), or more bytes in all than its total (10 MiB by default), counting the files a method bundle ships for its steps. |
65
- | `413` | `BundleResourcesTooLargeError` | The `.html` template files, which travel inline with the method wherever it runs, over 512 KiB in all. An office template file is not counted, since a run handed to a remote orchestrator carries it by reference to the run's storage. |
66
- | `400` | `InvalidBase64` | A value that is not base64, which a request this SDK encoded never carries. |
67
-
68
- ## A step whose file was not sent
69
-
70
- A step that names a template file the request did not send cannot load. On `validate`, `pipeIo`, `resolve` and `codegen` that is an `is_valid: false` verdict whose validation error says the file was not supplied with its bundle and names the key it is expected under; `prepareInputs` throws it as a `MethodLoadError`. On `execute` and `start` it is a `422` `ValidateBundleError`, whose `validationErrors` say the same.
71
-
72
- ## The template check's warnings
73
-
74
- A dry run hands an office template file it was sent to the document engine's template check. An error finding fails the step's dry run, and so the verdict, as a `dry_run` validation error on the step. A warning finding, such as a field of the template that matches no input, rides the valid verdict's `warnings` as a `template_check_warning` item:
75
-
76
- | Member | Value |
77
- | --- | --- |
78
- | `category` | `dry_run` |
79
- | `error_type` | `template_check_warning` |
80
- | `pipe_code`, `domain_code` | The `PipeDocGen` step |
81
- | `template_file` | The template file as the step names it; `null` for a step of the server's own library, whose path is never shown |
82
- | `template_location` | The place in the file the finding names, in the engine's words (a defined name, a table, a cell, a shape, a tag); `null` when it names none |
83
- | `message` | The finding in words |
84
-
85
- The warnings come in families, always in this order: `optional_force_redundant`, `input_presence_vacuous`, the `hint_*` lints, then `template_check_warning`. None of them flips `is_valid`.
86
-
87
- ```ts
88
- if (verdict.is_valid) {
89
- for (const warning of verdict.warnings) {
90
- if (warning.error_type === "template_check_warning") {
91
- console.warn(`${warning.template_file ?? "?"} ${warning.template_location ?? ""}: ${warning.message}`);
92
- }
93
- }
94
- }
95
- ```
96
-
97
- ## Method bundles
98
-
99
- On `execute` and `start`, a method bundle sent as a zip (`bundle_b64`) may ship a template file beside the `.mthds` file whose step names it, as it sits on disk, and the runner reads it as if it had come in `resources`, under the same limits. A file both shipped and sent must hold the same bytes. The `files` map of a method bundle carries text, so it can ship an `.html` template but not an office one, which goes in `bundle_b64` or in `resources`.
100
-
101
- ## The `.mthds` check hook
102
-
103
- The post-edit hook this package builds sends the template files of the bundle it validates: see [`hook-bundle.md`](./hook-bundle.md#what-the-hook-does-with-a-file).
104
-
105
- ## Which servers read them
106
-
107
- A `pipelex-api` runner reads `resources` from the first pipelex release after 0.84.0. The hosted API reads them once its platform forwards them to a runner on such a release. A runner that predates the field ignores it, so a step that names a template file fails to load there, the verdict saying the file was not supplied.